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. 如何保证重试的幂等性?

学习清单

  • 能举出“两事务、两行、相反锁顺序”的死锁例子。
维护与整理 · Yihui在 GitHub 上编辑

继续阅读

浏览全部文章

SQL与NoSQL有什么区别?MySQL和MongoDB如何选型?实际项目中如何选择?

日期:2026-09-27 标签:#面试 #MySQL #数据库 难度:简单 来源:牛面 MySQL 题库 答案说明:独立整理(站内题目标记为 VIP,未读取会员答案) 一句话答案 MySQL与MongoDB的主要差异在数据模型、事务边界、查询方式和模式演化;按业务访问模式和一致性需求选型。 面试口语版(约 60…

阅读全文