选择查询的事务死锁

时间:2011-04-29 00:30:05

标签: sql tsql concurrency deadlock

有时,对于只有Select查询的存储过程,我有以下错误:Transaction (Process ID 91) was deadlocked on lock

我最初的理解是,一个select查询不会锁定一个表,或者即使它试图查询的表正在被另一个进程更新/锁定,也不会导致死锁,但似乎一个select查询可以导致死锁。

如果我将隔离级别设置为读取未提交的读取,那么会解决问题吗?

3 个答案:

答案 0 :(得分:43)

  

我的初步理解是选择   查询不会锁定表,也不会   引起僵局

这种理解是错误的。 SELECT查询对它们分析的行执行共享锁定。共享锁可能会与update / delete / insert语句中的排它锁冲突。两个SELECT语句不会死锁,但SELECT可以使用UPDATE死锁。当发生这样的死锁时,SELECT通常是受害者,因为它没有执行任何更新,因此总是会松开抽奖。

与任何死锁一样,您需要发布所涉及的表的确切模式,确切的T-SQL语句和死锁图。见How to: Save Deadlock Graphs (SQL Server Profiler)。有了这些信息,您可以获得如何解决死锁的指导。

答案 1 :(得分:6)

像Remus说的那样,你得到了死锁,因为SELECT和UPDATE(或其他)操作相互死锁,而不是SELECT vs SELECT。您将不得不查看触及该表的所有查询,并为这些查询创建适当的覆盖索引,这将解决您的问题。良好的覆盖索引是首选解决方案,而不是使用WITH(NOLOCK)表提示。

有关如何创建覆盖索引及其如何影响死锁的详细教程,请参阅以下link

答案 2 :(得分:3)

如果您使用的是SQL Server 2008,则可以将隔离级别设置为read uncommitted以防止死锁。见link。当读取未提交或WITH(NOLOCK)时,必须注意查询重新创建的数据可能不是真实的!