我正在尝试在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
UPD 已经给出了答案但是接下来我正在插入死锁图的建议
答案 0 :(得分:1)
在这两种情况下,选择都使用共享锁并更新独占锁。
在READ COMMITTED模式下,选择完成后立即释放共享锁。
在REPEATABLE READS模式下,选择的共享锁保持在事务结束之前,以确保没有其他会话可以更改已读取的数据。除非在当前会话/事务中更改了数据,否则同一事务中的新读取将获得相同的结果
最初我想,你执行了#34; First"在两个会议中。然后解释将是微不足道的:两个会话获取并获得共享锁,然后阻止更新所需的独占锁。
第二个会话仅执行更新的情况稍微复杂一些。更新程序将首先获取更新锁(UPDLOCK)以选择必须更新的行,这可能类似于共享锁,但至少不会被共享锁阻止。接下来,当数据实际更新时,它会尝试将更新锁转换为独占锁,但这会失败,因为第一个会话仍然保持共享锁。现在两个会话互相阻塞。