mysql锁等待超时Lock wait timeout exceeded; try restarting transaction分析和代码层面以及数据库层面解决方案

mysql锁等待超时Lock wait timeout exceeded; try restarting transaction分析和代码层面以及数据库层面解决方案

1.首先看下案发现场

org.springframework.dao.CannotAcquireLockException:
Error updating database. Cause: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
The error may involve com.xxx.mapper.OrderMapper.updateByPrimaryKeySelective-Inline
The error occurred while setting parameters
SQL: update order set status = ?, code = ? … where id =111

2.发生场景

1、在同一事务内先后对同一条数据进行插入和更新操作;
2、多台服务器操作同一数据库;
3、瞬时出现高并发现象;
4、在同一个事务内出现操作时间过长的sql执行
5、cpu过高被其他线程占用,导致执行事务的那个线程执行时间过长

3.数据库层面解决方案

一般出现这种情况是存在有的事务未提交,当前事务正在等待那个未提交的事务出现的锁等待时间较长,导致的。mysql的锁等待时间默认是50s 超过这个时间就会抛出如上异常。
如果只是偶尔出现这样的情况,可以直接查看数据库中的锁住的进程,kill掉即可。
参考方法:https://blog.csdn.net/qq_39403545/article/details/88688028?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

4.代码方面解决方案

1.首先看下锁住超时的报错那行执行的sql所在的代码中,是不是存在一个事务中有多个更新操作,查出是哪个更新操作耗时,将这个大事务拆分成小的。另外事务中不要有查询时间过长的sql,可以将sql查询的逻辑放大事务的外边,进行传参到这个事务方法中。如果存在批量更新操作,可以用批量执行的逻辑,写成for循环,每条执行。
一个大事务中有多个更新操作,如果其中一个耗时,那么整个事务就耗时,可能会报错锁等待超时
在这里如插入图片描述如图中跟更新表1 耗时10s, 更新表2耗时55s, 更新表3耗时40s
这样的话整个事务耗时 是 10 + 30 + 40 > 默认50s。 在第一个逻辑更新表1的sql已经执行完,但是事务还未提交,等待下面的两个事务执行完再提交。而这时第一个更新逻辑在等到超过50s时,所以就报超时错误。
解决方法:将这个大事务拆分开

还有就是需要看下cpu是否过高,如果过高则存在大量·线程在操作这个事务逻辑,也会出现锁表的情况。
cpu过高的情况参考:https://blog.csdn.net/chenjunan888/article/details/80447800

如果上述问题没有解决,有可能是GC执行fullGC,出现了问题,需要排查具体代码,打印堆栈看下情况。具体在排查
参考博文:https://blog.csdn.net/wilsonpeng3/article/details/70064336?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

https://blog.csdn.net/n8765/article/details/50911742?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值