我遇到了死锁问题,我发现它是由两个不同线程调用的存储过程引起的(2个称为Web服务)。
此外,我得到的结果告诉我在X表的非唯一和非聚集索引中发生的死锁。你有什么想法解决这个问题吗?
更新
从Read/Write deadlock开始,由于以下陈述,我认为这是错误的。
所以,我需要为删除语句选择id,如下面的语句。
SELECT id FROM X WITH(NOLOCK) WHERE [condition]
PS。两个存储过程都在事务中调用。
谢谢,
答案 0 :(得分:4)
我们必须看到某种代码......你提到了一个交易;它的隔离级别是什么?要尝试的一件事是将(UPDLOCK)
提示添加到用于查找行的任何查询(或检查存在);所以你将从一开始就取出写锁(而不是读锁)。
当有争议时,这应该导致(非常短暂的)阻塞而不是死锁。
答案 1 :(得分:0)
存储过程是否会修改任何内容,或者只是执行读取操作?如果修改某些东西,那么更新的条款是否足够粒度?如果您可以尝试以较小批量更新行,则SQL Server不太可能发生死锁,因为它只会锁定少量索引,而不是整个索引。
如果有可能,你可以在这里发布死锁的代码吗?如果存储过程太长,你可以在其中发布有问题的陈述(如果你知道它们是哪个)?
答案 2 :(得分:0)
没有死锁信息更多的是猜测而不是正确答案......可能是类似于read-write deadlock的索引访问顺序问题。
答案 3 :(得分:0)
可能是选择查询是实际问题,特别是如果它们在两个存储过程中是相同的表,但是以不同的顺序。重要的是要记住,从表中读取将创建(共享)锁。您可能希望阅读lock types。
同样的情况可能发生在指数级别,正如Remus发布的那样。他联系的The article提供了一个很好的解释,但遗憾的是没有人能够解决这个问题,因为每个案例都没有一个最佳解决方案。
我自己并不是这个领域的专家,但是使用lock hints,您可以确保相同的资源以相同的顺序锁定,从而防止死锁。您可能需要测试人员提供更多信息才能有效地解决这个问题。
答案 4 :(得分:0)
让应用程序恢复正常运行的快速方法是检测死锁错误(1205)并重新运行事务。代码可以在联机丛书的“TRY ... CATCH”部分找到。
如果要删除和插入,那么这会影响聚簇索引,并且表上的每个非聚集索引也需要插入/删除。因此,发生死锁肯定是非常可能的。我将从查看聚簇索引的内容开始 - 例如,尝试使用聚簇索引的代理键。
不幸的是,如果没有更多信息,几乎不可能完全解决你的死锁问题。
罗布