订单服务对 1213 做了三次重试,上线后日志里出现同一笔单连续 5 次 Deadlock found,最后返回失败,死锁率没降。乍看像缓存或者权限的锅,追下去往往不是。

SHOW ENGINE INNODB STATUS\G
SHOW GLOBAL STATUS LIKE 'Innodb_deadlocks';

追下去是这么回事:重试没有退避,几个请求同时被回滚又同时重来,还是按原来的顺序加锁,环很快再次形成。重试次数越多,撞上的概率越高。根因是加锁顺序不固定,重试只是把同一场冲突重复一遍。

碰到「死锁重试」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。

具体做法是,重试前加随机退避 几十毫秒就够打散;固定多表更新的加锁顺序 按主键升序处理;重试只包住事务 不要包住整个业务方法;统计重试次数和最终失败率 判断是冲突太多还是逻辑有环。

验收就看一点,同一笔单不再连续出现 1213 Innodb_deadlocks 增速下降 重试后成功率回到正常。

作者 9823189