MySQL已产生死锁的解决方法及永久避免方案
引言
死锁是多个事务互相持有对方需要的锁,且都不释放,导致互相无限等待的现象,MySQL 会自动检测并终止其中一个事务(抛出死锁异常),让另一个正常执行。
你现在的核心需求分两步:
- 紧急处理:已经发生死锁,怎么快速恢复业务?
- 根治问题:怎么让死锁不再频繁出现?
一、已经产生死锁:3步快速解决
1. 无需手动杀进程!MySQL 会自动处理
MySQL 内置死锁检测(默认开启),一旦检测到死锁:
- 立即回滚代价最小的那个事务
- 给应用抛出
Deadlock found when trying to get lock; try restarting transaction异常 - 另一个事务会自动继续执行,死锁瞬间解除
结论:已发生的死锁不需要人工干预,MySQL 自己会秒级解决。
2. 查看死锁日志:找到根源(最重要)
死锁已经发生,必须查日志定位原因,执行命令:
-- 查看最近一次死锁的详细信息 SHOW ENGINE INNODB STATUS;
在结果中找到 LATEST DETECTED DEADLOCK 段落,里面会告诉你:
- 哪两个事务死锁了
- 各自执行的 SQL
- 各自持有什么锁、等待什么锁
- 死锁发生的时间
这是解决死锁的唯一依据。
3. 临时应急:卡住的事务不自动解除?
极少数情况(关闭了死锁检测),事务会一直卡住,执行以下命令手动处理:
-- 1. 查看正在运行的事务,找到卡住的 ID SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX; -- 2. 杀掉卡住的事务 KILL 事务ID;
二、永久避免死锁:4个核心方案(必做)
死锁无法100%杜绝,但99%的死锁都能通过规范避免。
1. 事务保持短小,不要长事务
- 死锁概率和事务执行时间成正比
- 禁止在事务里嵌套:网络请求、文件IO、人工操作、sleep
- 原则:快进快出,执行完立即提交/回滚
坏例子
BEGIN; UPDATE 表 SET ...; -- 这里调用了外部接口,耗时3秒,锁一直持有,极易死锁 COMMIT;
2. 所有表固定访问顺序(最有效)
死锁的本质:访问顺序相反
- 事务A:先锁订单 → 再锁库存
- 事务B:先锁库存 → 再锁订单
→ 瞬间死锁
解决方案:
所有业务代码,必须按相同顺序操作表/行
例如:统一先操作库存,再操作订单。
3. 给查询条件加索引
无索引会导致行锁升级为表锁,死锁概率暴增。
-- 错误:无索引,会锁全表 UPDATE user SET money=100 WHERE name='张三'; -- 正确:name 有索引,只锁单行 UPDATE user SET money=100 WHERE name='张三';
死锁日志里如果看到 LOCK_MODE: X, REC_NOT_GAP: nil 基本就是无索引导致。
4. 业务代码捕获死锁异常,自动重试
死锁是偶发异常,重试就能成功,这是兜底方案。
Java 示例:
try {
// 执行数据库操作
} catch (SQLTransactionRollbackException e) {
if (e.getMessage().contains("Deadlock")) {
// 死锁异常,重试1-2次
retry();
}
}三、快速排查死锁 Checklist
- 执行
SHOW ENGINE INNODB STATUS;看死锁详情 - 检查两个事务是否访问表/行顺序相反
- 检查更新语句是否没有索引
- 检查是否有长事务
- 业务代码是否没有重试机制
总结
- 已产生的死锁:MySQL 自动回滚一个事务,无需手动处理
- 查死锁原因:用
SHOW ENGINE INNODB STATUS; - 根治死锁:固定访问顺序 + 加索引 + 短事务 + 代码重试
- 兜底:业务捕获死锁异常自动重试,用户无感知
到此这篇关于MySQL已产生死锁的解决方法及永久避免方案的文章就介绍到这了,更多相关MySQL已产生死锁解决与避免内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
解决MySQL安装重装时出现could not start the service mysql error:0问题的方法
这篇文章主要为大家详细介绍了解决MySQL安装重装时出现could not start the service mysql error:0问题的方法,感兴趣的小伙伴们可以参考一下2016-06-06
MySQL中between...and的使用对索引的影响说明
这篇文章主要介绍了MySQL中between...and的使用对索引的影响说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2023-07-07


最新评论