Yihui’s Blog

MySQL 中如果发生死锁应该如何解决?

日期:2026-07-11
难度:中等
标签:#面试 #MySQL #死锁 #事务

一句话答案

InnoDB 检测到死锁会主动回滚代价较小的一个事务,应用必须捕获死锁错误并有限重试;根治要通过统一加锁顺序、缩短事务、优化索引和减少锁范围。

面试口语版

死锁是循环等待,例如 T1 先锁 A 再等 B,T2 先锁 B 再等 A。InnoDB 有死锁检测,会选择一个 victim 回滚并返回 Deadlock found when trying to get lock,所以应用层要把这类错误视为可重试异常:事务整体回滚后重新执行,并设置次数、退避和幂等保护。排查用 SHOW ENGINE INNODB STATUS 看最近死锁,或开启 innodb_print_all_deadlocks;然后让相同业务按一致顺序访问记录、确保条件走索引、拆短事务,避免在事务中做 RPC。

关键细节

  • 死锁不是简单调大 innodb_lock_wait_timeout 能解决;那主要影响锁等待超时。
  • 重试必须包含整个事务,不能只重试失败的最后一句 SQL。
  • 高并发热点可通过队列、分段或业务串行化降低冲突。

面试官追问

  1. 死锁与锁等待超时如何区分?
  2. 为什么要按主键升序批量更新?
  3. 如何保证重试的幂等性?

学习清单

  • 能举出“两事务、两行、相反锁顺序”的死锁例子。
Maintained by · YihuiEdit on GitHub

Keep reading

View all posts