一次mysql死锁的排查过程一、背景17号晚上要吃饭了,看旁边的妹子和佐哥还在调代码,就问了下什么问题啊,还在弄,妹子说,在测试环境测试给用户并发发送卡券时,出现了死锁,但看代码没有死锁,问题如下图
看日志确实发生了死锁,按照死锁产生的原因:一般死锁是两把锁两个人争抢,每个人都获得其中一把,谁都不让谁,等待对方释放锁,死循环导致的,图示如下
不过这次说看代码没有问题,感觉这个问题比较诡异,跟他们说先吃饭,吃完,一起群力群策研究研究这个。二、问题点1. ### SQL: select * from score_user where user_id = ? for update,这个sql查询是发送了死锁三、排查过程1. 根据经验和死锁产生的条件,猜测代码并发执行,一个线程先锁住了表A的记录,另外一个线程由于原因没有线索表A记录,而锁住了表B的记录,接下来,锁住A记录的线程等待B的锁是否,锁住B的线程等待A的锁释放,所以产生了原因,所以先看代码2. 代码如下面所示,可以看到,基本逻辑,都是先插入score_gain_stream
Java代码
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED,rollbackFor = Exception.class)
public boolean generateScoreInfo(String userId, Integer score,
Long scoreRuleId, int scoreType, int scoreStatus, String scoreWay,
String orderId, String inviteeId, String reqId, Integer