提交读和可重复读示例比较

3
我将尝试在SQL Server Management Studio中执行以下两条查询(在单独的查询窗口中)。我按照这里输入的顺序依次运行它们。
当隔离级别设置为“READ COMMITTED”时,它们能够正常执行,但是当设置为“REPEATABLE READS”时,事务会发生死锁。
您能否帮助我理解这里的死锁是什么呢?
begin tran
declare @a int, @b int
set @a = (select col1 from Test where id = 1)
set @b = (select col1 from Test where id = 2)
waitfor delay '00:00:10'
update Test set col1 = @a + @b where id = 1
update Test set col1 = @a - @b where id = 2
commit

第二点:

begin tran 
update Test  set col1 = -1 where id = 1
commit
< p > < em > UPD 答案已经给出,但是根据建议,我插入了死锁图

< p > enter image description here


你尝试过在分析器中创建死锁图吗? - SQLChao
1个回答

1
在两种情况下,选择使用共享锁,更新使用独占锁。
在读提交模式下,共享锁在选择完成后立即释放。
在可重复读模式下,选择的共享锁将保持到事务结束,以确保没有其他会话可以更改已读取的数据。除非在当前会话/事务中更改了数据,否则同一事务中的新读取将保证产生相同的结果。
最初我认为您在两个会话中都执行了“First”。然后解释就很简单:两个会话都获取并获得共享锁,这会阻止更新所需的独占锁。
只有第二个会话进行更新的情况稍微复杂一些。更新语句首先会为必须更新的行获取更新锁(UPDLOCK),这可能类似于共享锁,但至少不会被共享锁阻塞。接下来,在实际更新数据时,它尝试将更新锁转换为独占锁,但失败了,因为第一个会话仍然持有共享锁。现在两个会话都互相阻塞。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接