首页 > 解决方案 > 单个事务中的多个读取查询

问题描述

这个答案声称事务对于多个读取语句也很有用。下面的测试用例是错误的还是需要相关的表才能返回一致的结果?

在控制台 #1 中执行以下命令:

set transaction isolation level serializable;
begin transaction;
select * from TableA;
waitfor delay '00:00:15';
select * from TableB;
commit transaction;

在控制台 #2 中,在这 15 秒的窗口中,执行以下操作:

set transaction isolation level serializable;
begin transaction;
insert into TableB(col) values('b');
commit transaction;

15 秒过去后,控制台 #1 返回其中包含一行'b'。为什么?我认为控制台#1 不会返回任何结果,或者事务#1 会中止,因为TableB已修改。

我在 Windows 上尝试过 SQL Server LocalDB 2017,在 Linux 上尝试过 SQL Server 2019 RC1。我使用 DataGrip 运行我的 sql 命令,但我使用 Entity Framework 6 的原始用例。

标签: sqlsql-servertransactionsisolation-leveltransaction-isolation

解决方案


控制台#1 执行返回针对TableB 的'b' 记录,因为控制台#2 在控制台#1 中TableB 的选择查询之前添加了TableB 中的记录。事务仅锁定已执行查询中存在的那些表。如果在选择 TableB 后等待添加,则控制台 #1 将不会获得“b”记录。如果表的结构发生更改,例如删除列并在选择查询之前添加新列,但如果未使用 *,则查询将被中止。如果在所选查询中按名称不存在 Drop 列,则不会生成错误。


推荐阅读