业务场景:微信支付模块,每一次请求都会在pay_log表里插入订单号等记录,支付回调时会更新pay_log表的记录
同时还有一个定时任务用来定时将所有1小时前的订单标记为交易超时
编写单元测试,模拟支付回调通知,结果出了异常,更新记录时出现死锁
大致SQL如下:
事务A
1 | Update pay_log SET tradeState = 2 WHERE tradeState=0 AND createTime < '2019-08-20 15:23:04.167' |
事务B
1 | INSERT pay_log VALUES(NULL,?,NOW(),?,?,?,?,?,?,?,?,?,?,?,?) |
然后事务B被回滚了
解决方案:要么禁用定时任务,要么去掉单元测试的事务手动回滚,要么单元测试不要打断点调试(定时任务设置了项目启动后10秒后启动)
附上MySQL死锁日志,其实这玩意只能大致的定位故障,因为可以看出事务2的SQL只有最后执行的那一条
1 | 2019-08-20 16:23:07 0x7ff1b2039700 |