选择/更新或多个选择之间的SQL Server死锁
所有关于SQL Server死锁的文档都讨论了操作1锁定资源A然后尝试访问资源B并且操作2锁定资源B并尝试访问资源A的场景。
然而,我经常在选择和更新之间,甚至在我们一些繁忙应用程序中的多个选择之间看到死锁。 我发现死锁跟踪输出的一些细节非常难以理解,但我真的想知道什么会导致两个单独操作之间的死锁。 当然,如果一个select有一个读锁定,更新应该在获得排它锁之前等待,反之亦然?
这发生在SQL Server 2005上,并不是我认为这有所作为。
我曾在SQL-Server-Performance.com上为一篇关于高级SQL Server锁定的好文章添加了书签。 那篇文章超越了你提到的经典僵局,并且可能会让你对你的问题有所了解。
这可能会发生,因为select会锁定两个不同的索引,同时更新将以相反的顺序锁定相同的索引。 该选择需要两个索引,因为第一个索引不包含所有需要访问的列; 更新需要两个索引,因为如果更新索引的键列,则需要锁定它。
http://blogs.msdn.com/bartd/archive/2006/09/25/770928.aspx有一个奇妙的解释。 建议的修复包括添加一个索引,该索引涵盖选择需要的所有列,切换到快照隔离,或者显式强制select选取它通常不需要的更新锁。
我很惊讶没有人提到WITH (UPDLOCK)
锁定提示。 如果有死锁涉及例如两个并行运行的select-insert对,那么这非常有用。
在SQL Server中,如果使用WITH (UPDLOCK)
发出选择,则第二个选择将等到第一个选择完成。 否则,他们会获得共享锁,当他们同时尝试升级到独占锁时,他们会死锁。
上一篇: SQL Server deadlocks between select/update or multiple selects