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

MySQL5.7 InnoDB同主键行更新触发死锁,S锁产生原因咨询

UPDATE语句触发死锁出现S锁的成因解析

首先明确核心结论:UPDATE语句本身不会主动加S锁,你在死锁日志里看到的S锁是对应事务执行这条UPDATE之前,由其他操作提前加上的。

结合你提供的死锁日志可以看到两个事务的undo log entries值均为25,说明两个事务都不是仅执行了这一条UPDATE的单语句事务,在执行当前UPDATE之前已经完成了25次数据修改操作,S锁就是在这些前置操作中产生的,常见的触发场景有以下三类:

  • 显式加共享锁操作:事务前置逻辑中执行了SELECT ... LOCK IN SHARE MODE(MySQL 5.7版本的共享锁查询语法),提前给PK=1的记录加上了S锁,之后执行同记录的UPDATE时需要将S锁升级为X锁。此时两个事务同时持有该记录的S锁,都要申请X锁,而S锁与X锁互斥,就会形成循环等待触发死锁。
  • 唯一键冲突隐式加S锁:两个事务都先尝试插入PK=1的记录,触发唯一键冲突后,InnoDB会自动给已存在的PK=1的记录加S锁做冲突校验,之后两个事务都转做UPDATE操作,就会出现都持有S锁、同时申请X锁的死锁场景,这是业务中最常见的诱因。
  • 外键约束隐式加S锁:如果Test_Table存在外键关联,更新操作触发外键一致性校验时,InnoDB会自动给关联表的对应记录加S锁,如果两个事务的校验逻辑刚好都先拿到了PK=1记录的S锁,再申请X锁也会触发死锁。

对应优化方案

  • 排查业务代码中对应事务的执行逻辑,定位S锁的产生来源,优先避免在同一个事务中先对同一行加S锁再执行修改操作。
  • 如果有显式加锁的需求,直接用SELECT ... FOR UPDATE加X锁代替共享锁,避免锁升级的冲突。
  • 唯一键冲突场景下,使用INSERT ... ON DUPLICATE KEY UPDATE语法替代先插入后更新的逻辑,减少S锁的产生概率。
  • 若业务侧可以自行保证数据一致性,可以考虑去掉不必要的外键约束,减少隐式加锁的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 12:54:08