You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server死锁咨询:重复锁条目及锁模式差异等问题

SQL Server 3进程死锁问题分析

一、resource-list中相同ID的keylock重复出现的原因

死锁XML里重复出现相同id的keylock条目,并非存在多个相同的行锁资源,而是SQL Server为了清晰展示不同进程与同一锁资源的交互关系拆分记录的结果。本质上这些重复条目指向的是同一个行级排他锁(X锁),只是分别记录了不同进程对该锁的持有、等待状态。

二、keylock、owner、waiter元素的mode属性区别

  • keylock的mode:代表当前锁资源最终被持有的锁模式,是锁资源本身的状态。比如示例中的mode="X",说明这个行锁当前处于排他锁状态,不允许其他进程获取共享/排他锁。
  • owner的mode:代表持有该锁的进程所持有的锁模式。如果owner节点带有requestType="wait",则表示该进程正在等待获取该模式的锁;若没有该属性,说明进程已成功持有对应模式的锁(如第一个owner的mode="X",表示进程已持有排他锁)。
  • waiter的mode:代表等待该锁的进程请求的锁模式。示例中的mode="S"表示等待进程正在请求共享锁,由于当前锁是排他锁,共享锁请求会被阻塞。

三、死锁发生原因及环境差异问题

死锁根源

虽然每个进程操作唯一主键,但仍可能触发死锁:

  1. 事务范围与锁持有时间:存储过程中更新后未及时提交事务,导致排他锁长时间持有;后续查询请求共享锁,高并发下形成循环等待(如示例中3个进程形成A→等待C的锁、C→等待B的锁、B→等待A的锁的循环)。
  2. 查询扫描范围扩大:生产环境主键索引存在碎片,或执行计划因数据量差异发生变化,导致查询未精准定位单行,而是扫描到其他进程持有的行,触发锁等待。
  3. 隔离级别影响:默认的READ COMMITTED隔离级别下,查询会请求共享锁,若更新操作的排他锁未释放,就会引发锁竞争。

开发环境无法复现的原因

  • 开发环境并发量极低,无法触发3个进程恰好形成循环等待的时序;
  • 开发环境数据量小,执行计划更优,查询能精准定位单行,不会扫描到其他行;
  • 开发环境的隔离级别、锁配置与生产环境不一致(如开发环境开启了快照隔离)。

解决建议

  • 缩小事务范围:更新操作后立即提交事务,或确保事务仅包含必要的更新、查询步骤,减少锁持有时间;
  • 开启快照隔离:启用READ COMMITTED SNAPSHOT ISOLATION,让查询读取版本化数据,无需请求共享锁,避免锁阻塞;
  • 优化主键索引:定期重建/重组PK_Orders索引,消除碎片,确保查询精准定位单行;
  • 验证查询语句:确认查询的过滤条件严格匹配唯一主键,避免扫描额外行;
  • 调整锁提示:必要时在查询语句中添加WITH (NOLOCK)(需权衡一致性)或WITH (ROWLOCK),强制行级锁。

死锁XML片段

<resource-list>
            <keylock hobtid="72057616768958464" dbid="16" objectname="Orders"
                indexname="PK_Orders" id="lock223c94b6980" mode="X"
                associatedObjectId="72057616768958464">
                <owner-list>
                    <owner id="process218b9814ca8" mode="X" />
                </owner-list>
                <waiter-list>
                    <waiter id="process218bb8dcca8" mode="S" requestType="wait" />
                </waiter-list>
            </keylock>
            <keylock hobtid="72057616768958464" dbid="16" objectname="Orders"
                indexname="PK_Orders" id="lock223c94b6980" mode="X"
                associatedObjectId="72057616768958464">
                <owner-list>
                    <owner id="process218bb8dcca8" mode="S" requestType="wait" />
                </owner-list>
                <waiter-list>
                    <waiter id="process218bb829468" mode="S" requestType="wait" />
                </waiter-list>
            </keylock>
            <keylock hobtid="72057616768958464" dbid="16" objectname="Orders"
                indexname="PK_Orders" id="lock2240f4bb680" mode="X"
                associatedObjectId="72057616768958464">
                <owner-list>
                    <owner id="process218bb829468" mode="X" />
                </owner-list>
                <waiter-list>
                    <waiter id="process218b9814ca8" mode="S" requestType="wait" />
                </waiter-list>
            </keylock>
</resource-list>

内容的提问来源于stack exchange,提问作者Jun Qian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 03:02:04