厦门市建设工程质监站网站都匀网站制作公司
2026/4/6 4:02:26 网站建设 项目流程
厦门市建设工程质监站网站,都匀网站制作公司,建设网站主机可以用吗,wordpress 模板 黑暗关注我们,设为星标,每天7:30不见不散,每日java干货分享你的电商系统正在进行大促。突然#xff0c;支付服务疯狂报错#xff1a;java.sql.SQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction你的反应#xff1a;你知道发…关注我们,设为星标,每天7:30不见不散,每日java干货分享你的电商系统正在进行大促。突然支付服务疯狂报错java.sql.SQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction你的反应你知道发生了死锁但你不知道是哪两个业务逻辑撞车了。你颤颤巍巍地在数据库里敲下了那行命令SHOW ENGINE INNODB STATUS\G;屏幕上吐出了一大坨像乱码一样的日志。别慌我们只看LATEST DETECTED DEADLOCK这一节。1. 核心原理死锁日志的“三段式”结构死锁日志记录的是案发那一刻的快照。它通常由三部分组成1.事务 (1) (TRANSACTION 1):“受害者”或者“凶手”之一。它手里拿着什么锁正在等什么锁。2.事务 (2) (TRANSACTION 2):另一个“凶手”。它手里拿着什么锁正在等什么锁。3.判决结果 (WE ROLL BACK TRANSACTION):MySQL 的裁判死锁检测器决定杀掉哪个事务来打破僵局。2. 实战解码经典“AB-BA”死锁这是最容易读懂的死锁类型。日志片段还原------------------------ LATEST DETECTED DEADLOCK ------------------------ *** (1) TRANSACTION: TRANSACTION 12345, ACTIVE 5 sec starting index read mysql tables in use 1, locked 1 LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s) MySQL thread id 100, OS thread handle ..., query id ... # 注意这里显示的是事务 1 正在尝试执行的 SQL UPDATE accounts SET balance balance - 100 WHERE id 1 *** (1) WAITING FOR THIS LOCK TO BE GRANTED: # 事务 1 正在等 ID1 的 X 锁排他锁 RECORD LOCKS space id 54 page no 4 n bits 72 index PRIMARY ... trx id 12345 lock_mode X locks rec but not gap waiting Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000001; asc ;; -- 这里 hex 1 代表 ID1 *** (2) TRANSACTION: TRANSACTION 12346, ACTIVE 3 sec starting index read ... # 事务 2 正在尝试执行的 SQL UPDATE accounts SET balance balance 100 WHERE id 2 *** (2) HOLDS THE LOCK(S): # 事务 2 手里已经拿到了 ID1 的 X 锁 RECORD LOCKS space id 54 page no 4 n bits 72 index PRIMARY ... trx id 12346 lock_mode X locks rec but not gap Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000001; asc ;; -- 又是 ID1 *** (2) WAITING FOR THIS LOCK TO BE GRANTED: # 事务 2 正在等 ID2 的 X 锁 ... hex 80000002 ... *** WE ROLL BACK TRANSACTION (1)侦探分析1.看HOLDS THE LOCK(S):事务 2 持有 ID1 的锁。2.看WAITING FOR THIS LOCK:事务 1 想要 ID1 的锁被阻塞。事务 2 想要 ID2 的锁。3.推导逻辑•事务 1:已经锁住了 ID2 (虽然日志没显式写它持有但因为它在等 ID1且形成了死锁说明它手里必有筹码)现在想锁 ID1。•事务 2:已经锁住了 ID1现在想锁 ID2。4.结论典型的资源顺序冲突。• 线程 ALock(2) - Lock(1)• 线程 BLock(1) - Lock(2)实战场景两个用户互相转账。3. 进阶解码看不懂的“间隙锁” (Gap Lock)很多时候你发现日志里只有INSERT语句并没有 Update为什么也会死锁这时候要关注关键词lock_mode X locks gap before rec或insert intention。日志片段还原*** (1) TRANSACTION: INSERT INTO users (id, name) VALUES (10, Alice) *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS ... index PRIMARY ... # 注意关键词insert intention (插入意向锁) lock_mode X locks gap before rec insert intention waiting *** (2) TRANSACTION: INSERT INTO users (id, name) VALUES (10, Bob) *** (2) HOLDS THE LOCK(S): # 注意关键词locks gap before rec (间隙锁) RECORD LOCKS ... index PRIMARY ... lock_mode X locks gap before rec侦探分析1.场景这是一个INSERT导致的死锁通常发生在唯一索引冲突或范围删除后。2.解读•事务 2持有一个Gap Lock间隙锁。这通常是因为它之前执行了一个DELETE FROM users WHERE id 5或者SELECT ... FOR UPDATE锁住了一片范围。•事务 1想要在这个范围内INSERTid10。插入操作需要获取Insert Intention Lock插入意向锁。•规则插入意向锁会被间隙锁排斥。3.隐形杀手如果事务 2 自己也想在这个间隙里插入数据或者两个事务同时对同一个不存在的记录加锁SELECT * FROM t WHERE id 10 FOR UPDATE就会形成死锁。实战场景•并发初始化数据两个线程同时检测到数据不存在同时执行插入INSERT IGNORE或INSERT ... ON DUPLICATE KEY。•消息队列消费多个消费者同时处理幂等逻辑。4. 关键术语对照表 (Rosetta Stone)读日志时只要看懂这几个词能解决 90% 的问题术语含义人话解释lock_mode X排他锁 (Exclusive)“我要改这条数据谁也别动”lock_mode S共享锁 (Shared)“我要读这条数据你们别改但可以读”locks rec but not gap记录锁 (Record Lock)“我只锁这一行不锁前后的缝隙”locks gap before rec间隙锁 (Gap Lock)“我锁的是这行前面的空隙禁止插入”insert intention插入意向锁“我想插队那个拿着间隙锁的大哥让让路”Next-Key Lock临键锁记录锁 间隙锁默认级别下的锁5. 总结与行动指南当你拿到死锁日志后按照以下步骤行动1.找 SQL在日志里找到TRANSACTION 1和TRANSACTION 2分别在执行什么 SQL。2.找索引看index PRIMARY还是index idx_name确定是锁主键还是锁二级索引二级索引死锁非常常见。3.看模式• 如果是AB-BA互斥锁调整代码里的加锁顺序保证所有线程都按ID升序加锁。• 如果是Gap / Insert Intention间隙锁优化索引尽量让 Update/Delete 命中唯一索引退化为行锁减少锁的范围。最后一句忠告SHOW ENGINE INNODB STATUS只保留最后一次死锁的信息。如果死锁频发建议开启全局参数innodb_print_all_deadlocks ON让每一次死锁都记录到 MySQL 的错误日志error.log里方便事后复盘。推荐阅读 点击标题可跳转50个Java代码示例全面掌握Lambda表达式与Stream API16 个 Java 代码“痛点”大改造“一般写法” VS “高级写法”终极对决看完代码质量飙升为什么高级 Java 开发工程师喜爱用策略模式精选Java代码片段覆盖10个常见编程场景的更优写法提升Java代码可靠性5个异常处理最佳实践为什么大佬的代码中几乎看不到 if-else因为他们都用这个...还在 Service 里疯狂注入其他 Service你早就该用 Spring 的事件机制了看完本文有收获请转发分享给更多人关注「java干货」加星标提升java技能❤️给个「推荐 」是最大的支持❤️.cls-1{fill:#001e36;}.cls-2{fill:#31a8ff;}.cls-1{fill:#001e36;}.cls-2{fill:#31a8ff;}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询