加载中...

| MySQL 错误码 | ERROR 1213 (40001) |
| InnoDB 检测机制 | 等待图(Wait-for Graph)循环检测 |
| 解决手段 | 回滚权重最小的事务,应用层重试 |
经典的死锁场景:事务 A 先锁住行 1,再试图锁行 2;与此同时事务 B 先锁住行 2,再试图锁行 1。双方都在等对方释放锁,于是陷入循环等待。这不是程序 bug,而是任何允许并发写的系统都可能遇到的必然现象。
InnoDB 每隔约 50ms 运行一次死锁检测,发现循环依赖后会选择回滚权重最小的事务(通常是撤销操作量最少的那个),并向应用层返回错误 ERROR 1213 (40001): Deadlock found。应用层应当捕获这个错误并重试整个事务。[1]
减少死锁没有银弹,但有几条实用原则:固定加锁顺序——所有事务按相同的表和行顺序获取锁,循环依赖就不会出现;缩短事务——锁持有时间越短,冲突窗口越小;避免大事务——一次操作大量行会长时间持有许多锁。
MySQL 提供了 SHOW ENGINE INNODB STATUS 命令,输出中的 LATEST DETECTED DEADLOCK 段落会显示最近一次死锁涉及的两个事务、各自持有和等待的锁,是排查死锁的第一步。PostgreSQL 则通过日志记录死锁详情,并在 deadlock_timeout(默认 1s)后触发检测。

| MySQL 错误码 | ERROR 1213 (40001) |
| InnoDB 检测机制 | 等待图(Wait-for Graph)循环检测 |
| 解决手段 | 回滚权重最小的事务,应用层重试 |
登录 后参与讨论
暂无讨论,来发表第一条评论吧