是否所有死锁都是由错误的查询引起的

时间:2010-03-23 16:05:36

标签: sql-server deadlock

“事务(进程ID 63)在锁定通信缓冲区资源上与另一个进程死锁,并被选为死锁牺牲品。重新运行该事务。”可能的失败原因:查询问题,“ResultSet”属性设置不正确,参数设置不正确或连接未正确建立。“

这个死锁是否可能是因为存储过程使用的东西像SQL邮件一样?或者它总是导致我的两个应用程序同时访问同一个表?

3 个答案:

答案 0 :(得分:8)

同时访问同一个表的两个表一直在应用程序中发生。通常这不会导致死锁。当您说进程'A'尝试更新表1然后再更新表2然后表3时,通常会发生死锁,并且您有进程'B'尝试更新表3,然后是表2,然后是表1.进程' '将'资源锁定,进程'B'需要,进程'B'有资源进程'A'需要。 SQL Server将此检测为死锁,并将其中一个进程作为失败的事务回滚。

底线是你有两个进程试图同时更新相同的表,但不是以相同的顺序。这通常会导致死锁。

在您的应用程序中处理此问题的一种简单方法是处理失败的事务并简单地重新执行事务。它几乎总能成功执行。更好的解决方案是确保您的流程尽可能以相同的顺序更新表。

答案 1 :(得分:4)

缺少索引是导致死锁的另一个常见原因。如果select查询可以从索引而不是基表获取所需的信息,那么表本身上的任何更新/插入都不会阻止它。

要确定,请使用SQL事件探查器跟踪“死锁图”事件,它将显示死锁本身的详细信息。

答案 2 :(得分:2)

基于this,我认为SQL Mail本身不会直接成为罪魁祸首。我说“直接”因为我不知道你在做什么。但是,我假设 SQL Mail与其他SQL操作相比可能很慢,所以如果你做了很多,那么它可能会间接地造成一个瓶颈,如果你'导致死锁'在发送SQL Mail时重新保持表格。

如果没有太多关于你正在做什么的具体细节,很难推荐一个具体的策略。缺点是你应该考虑是否有办法在你这样做的时候打破你对表的依赖,例如使用NOLOCK,使用临时表或非临时“保持”表或只是重构SP那是在打电话。