繁体   English   中英

SQL Server 2008 R2 查询通知上的死锁 (SqlDependency)

[英]SQL Server 2008 R2 DeadLock on query Notification (SqlDependency)

我在 SQL Server 2008 R2 上遇到了死锁问题。 查看 SQL Profiler 中的死锁图时,问题似乎源于查询通知:

  <resource-list>
   <keylock hobtid="72057654759522304" dbid="6" objectname="MyDB.sys.query_notification_814081939" indexname="cidx" id="lock15ab2aa80" mode="RangeX-X" associatedObjectId="72057654759522304">
    <owner-list>
     <owner id="process5c5708" mode="RangeX-X"/>
    </owner-list>
    <waiter-list>
     <waiter id="process4e9ae08" mode="RangeS-U" requestType="wait"/>
    </waiter-list>
   </keylock>
   <keylock hobtid="72057654759522304" dbid="6" objectname="MyDB.sys.query_notification_814081939" indexname="cidx" id="lock15e56a300" mode="RangeS-U" associatedObjectId="72057654759522304">
    <owner-list>
     <owner id="process4e9ae08" mode="RangeS-U"/>
    </owner-list>
    <waiter-list>
     <waiter id="process5c5708" mode="RangeS-U" requestType="wait"/>
    </waiter-list>
   </keylock>
  </resource-list>

这些查询通知是使用 SQLDependency 实现的。 更新 SQLDependency 监视的表时似乎发生死锁。

我不是很懂死锁图的语法。KeyLock 模式只有在使用可序列化事务隔离级别时才是 RangeS-U , 对 ?

我也读过这个问题……我应该激活 READ_COMMITED_SNAPSHOT 吗?

谢谢...

不能确定,但​​这里有一些想法......

在传递通知之前,导致通知的语句可能不会完成。 因此,在从服务代理接收到通知并对通知采取任何操作时,它可能仍然具有活动锁。

也许您的通知接收者正在尝试清理队列或在生成第一个通知的事务完成之前从队列中获取第二个通知。

生成通知的 DML 是否在多步事务中运行? 是在多步事务中运行的接收通知的代码。 (即您是否使用了 begin tran 或等效的?)。

跟踪死锁图中提到的进程并了解哪些代码持有 RangeX-X 锁以及哪些代码持有 RangeS-U 可能很有用。

您可能希望发布一些生成通知的代码和接收通知的代码的最小示例。

这里还有一个 Microsoft KB,关于通知和多个订阅的已知有点类似的死锁问题。

MS KB975090 可能相关,但不完全相同。

这背后的主要原因是事务太长并且涉及太多对象。

正如我在我的问题中所说,触发 SqlDependency 的表包含对数据库中每个对象的引用。 在同一个事务中更新一堆对象意味着查询通知系统锁定了这个大表。 因此,您很快就会陷入僵局。

2个解决方案(由MS建议):

  • 减少事务的长度和复杂性。
  • 在大事务之外执行触发通知系统的请求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM