You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

请求分析SQL Server死锁XML文件内容

咱们来好好拆解下这个SQL Server死锁的XML日志,把问题掰扯清楚:

死锁核心概况

首先看受害者:**进程processa9f6f73c28**被SQL Server终止以打破死锁,它当时正尝试执行删除操作,等待一个排他锁(X)。

参与死锁的三个进程详情

进程1(受害者):processa9f6f73c28

  • 执行路径:调用存储过程[model].[RelationshipPair_DeleteByRelationshipIds],核心SQL是:
    DELETE RP FROM [model].RelationshipPair RP INNER JOIN @RelationshipIdTable RIT ON RP.RelationshipId = RIT.EntityI
    
  • 等待状态:需要对键资源KEY: 5:72057594060013568 (bd1a413b4dd8)排他锁(X),已等待1759ms
  • 基础信息:事务ID 19463226,隔离级别为默认的READ COMMITTED,来自.Net SqlClient Data Provider客户端

进程2:processa9f9857088

  • 执行路径:调用[model].[ModelItem_Relationship_Create] → 触发[model].[ModelItem_Generic_Create],核心是插入操作:
    INSERT INTO [model].[ModelItem] ( [MetamodelItemId], [ModelItemCategoryId] ) 
    OUTPUT [inserted].[ModelItemId], [inserted].[MetamodelItemId] INTO @ModelItemIdsByMetamodelId 
    SELECT EntityId, @ModelItemCategoryId FROM @MetamodelItemIdTabl
    
  • 等待状态:需要对键资源KEY: 5:72057594060013568 (3f1e49aa6519)共享范围锁(RangeS-S),已等待2779ms
  • 基础信息:事务ID 19414353,同样是READ COMMITTED隔离级别,和受害者来自同一客户端主机

进程3:processa9fb862108

  • 执行路径:调用[model].[ModelItem_Generic_Delete](XML内容被截断,但能看出来是删除操作)
  • 等待状态:需要对键资源KEY: 5:72057594060013568 (bd1a413b4dd8)共享范围锁(RangeS-S),已等待40ms
  • 基础信息:事务ID 19385479READ COMMITTED隔离级别,同一客户端主机
死锁根源分析

三个进程都在争抢同一个索引对应的键资源(72057594060013568是数据库5里的某个索引ID,大概率属于RelationshipPairModelItem表):

  1. 进程1(删除)要拿排他锁,但目标键已经被进程3持有了共享范围锁
  2. 进程3又在等进程1释放锁,同时进程2在等另一个键的锁,形成了循环等待的死锁链
  3. 所有进程都来自同一客户端实例,说明是服务内部的并发操作冲突导致的
初步解决建议
  • 缩短事务时长:检查存储过程里有没有没必要的延迟操作,把大事务拆小,减少锁的持有时间
  • 优化索引:看看涉及的两张表的索引是不是合理,让删除/插入更快,锁的持有时间更短
  • 调整隔离级别:如果业务允许,开启READ COMMITTED SNAPSHOT,用快照读避免阻塞;或者改写查询减少范围锁的产生
  • 应用层控制:对操作相同数据的请求做排队处理,避免同时执行冲突的删插操作

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

火山引擎 最新活动