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

存储过程更新表时出现Transaction死锁错误该如何解决?

死锁问题解决方案
  • 启用快照隔离或读提交快照隔离(RCSI)
    这是最推荐的方案,无需修改现有查询代码,仅需在数据库层面开启配置,开启后SELECT查询会读取行版本数据,不会申请共享锁,从根本上避免和UPDATE操作的排它锁产生冲突。开启命令参考:
    -- 开启读提交快照隔离
    ALTER DATABASE 你的数据库名 SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE;
    -- 如需更高隔离级别可开启快照隔离
    ALTER DATABASE 你的数据库名 SET ALLOW_SNAPSHOT_ISOLATION ON;
    
  • 添加针对性索引缩小锁范围
    确保两个UPDATE语句都能走高效索引,避免全表扫描导致锁定大量无关行,针对你当前的SQL,建议给table2添加联合索引:
    CREATE NONCLUSTERED INDEX IX_table2_ResultBundleId_IsCancelled 
    ON table2 (ResultBundleId, IsCancelled) 
    INCLUDE (LastModified, WorkflowStage);
    
    该索引可以让table2的UPDATE操作直接定位到需要修改的行,大幅减少锁的持有范围和时间。
  • 统一所有事务的锁获取顺序
    你当前的事务操作顺序是先更新table1再更新table2,需要确保所有操作这两张表的事务(包括其他更新、查询事务)都遵循相同的表访问顺序,消除死锁的循环等待必要条件。
  • 添加死锁重试逻辑
    死锁属于偶发异常,可在存储过程或者业务调用层添加错误捕获逻辑,当捕获到死锁错误号(1205)时,等待100-500毫秒后重新执行操作,建议设置最多3-5次重试阈值。
  • 可选:查询添加NOLOCK提示(仅业务允许脏读时使用)
    如果业务场景允许读取到未提交的临时数据,可以给并行运行的SELECT语句加上WITH (NOLOCK)提示,查询不会申请共享锁,也能避免和更新锁冲突,但要注意会有脏读、幻读等数据一致性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:51:01