一个进程成为死锁受害者的原因

我有一个选择过程需要很长时间才能完成,大约需要5到10分钟。
我目前不使用NOLOCK作为MS SQL数据库引擎的提示。
同时,我们有另一个进程进行更新并插入到相同的数据库和相同的表中。
第一个过程已经开始,最近过早地结束了一条消息

SQLEXCEPTION:事务在锁资源上与另一个进程死锁,并被选为死锁受害者。

这个第一个过程在其他网站上以相同的条件运行,但数据库较小,因此所选择的语句需要更短的时间(大约30秒左右)。 在这些其他网站中,我没有在这些其他网站中看到死锁消息。 我也没有在最初出现问题的网站上得到这个消息,但是,我认为,随着数据库的增长,我相信我必须跨越一些门槛。 这是我的问题:

  • 执行事务所花费的时间是否会使关联进程更可能被标记为死锁受害者。
  • 如果我使用NOLOCK提示执行选择,这会消除问题吗?
  • 我怀疑在SELECT语句中作为WHERE子句的一部分检查的日期时间字段会导致查找时间变慢。 我可以根据此字段创建索引吗? 这是可取的吗?

  • 问题1:执行事务所花费的时间是否会使关联进程更可能被标记为死锁受害者。

    不可以。SELECT是受害者,因为它只读取数据,因此交易的成本较低,因此被选为受害者:

    默认情况下,数据库引擎选择死循环受害者运行事务的会话,该事务回滚最便宜 。 或者,用户可以使用SET DEADLOCK_PRIORITY语句在死锁情况下指定会话的优先级。 DEADLOCK_PRIORITY可以设置为LOW,NORMAL或HIGH,或者可以设置为范围(-10到10)内的任何整数值。

    Q2。 如果我使用NOLOCK提示执行选择,这会消除问题吗?

    不是。有几个原因:

  • 您应该首先尝试通过调查根本原因来正确消除僵局
  • 脏读取是不一致的读取。
  • 指定脏读的正确方法是使用事务隔离级别
  • 有一个更好的解决方案:读取提交的快照。
  • Q3。 我怀疑在SELECT语句中作为WHERE子句的一部分检查的日期时间字段会导致查找时间变慢。 我可以根据此字段创建索引吗? 这是可取的吗?

    大概。 死锁的原因几乎很可能是一个索引不佳的数据库.10分钟的查询在这种狭窄的条件下是可以接受的,我对你的情况100%确定是不可接受的。

    凭借99%的信心,我声明您的死锁是由与更新冲突的大型表扫描引起的。 首先捕获死锁图来分析原因。 您很可能必须优化数据库的模式。 在您做任何修改之前,请阅读本主题设计索引和子文章。


    下面是这个特定的死锁问题是如何发生的以及它是如何解决的。 这是一个相当活跃的数据库,每天发生130K次交易。 此数据库中表中的索引最初是聚集的。 客户要求我们使索引非集群。 一旦我们做到了,僵局就开始了。 当我们将索引重新建立为聚簇时,死锁就停止了。


    这里的答案值得一试,但你也应该检查你的代码。 特别是在这里阅读Polyfun的答案:如何摆脱SQL Server 2005和C#应用程序中的死锁?

    它解释了并发问题,以及如何在查询中使用“with(updlock)”可能会更正您的死锁情况 - 具体取决于您的代码正在做什么。 如果你的代码确实遵循这种模式,那么在采用脏读之前,这可能是一个更好的解决方案,等等。

    链接地址: http://www.djcxy.com/p/32863.html

    上一篇: Cause of a process being a deadlock victim

    下一篇: How complete is the SQL Server 2008 deadlock graph executionStack?