1、程序中报错日志:
Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException:
Lock wait timeout exceeded; try restarting transaction;
Lock wait timeout exceeded; try restarting transaction;
nested exception is com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException:
Lock wait timeout exceeded; try restarting transaction
grep "MySQLTransactionRollbackException" *_2021-09-10.9.log
查找第一次出现位置:grep -C 100 "MySQLTransactionRollbackException"
*_2021-09-10.9.log | head -201
2、查看未提交事务:
select * from information_schema.INNODB_TRX;
SELECT
a.id,a.user,a.host,b.trx_started,b.trx_query
FROM information_schema.processlist a RIGHT OUTER JOIN information_schema.innodb_trx b
ON a.id = b.trx_mysql_thread_id;
3、手动执行该update语句,失败,等待锁超时:
update orders set *** where id='79302e18a8e848ccb2323c48ca4ca349';
update orders set *** where id='aeff09dbbc1a4668bf959f675d536ece';
4、由于是生产,客户急需处理业务数据,所以临时解决方案,是先kill 掉,未能提交事务的线程,
kill trx_mysql_thread_id(上图中的trx_mysql_thread_id是10, 所以 执行 kill 10)
5、准备在测试环境复现这个问题,测试开启之前,查询是否有未提交事务
6、测试环境查看:
-- 查看正在锁的事务(没有)
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
-- 查看等待锁的事务(没有)
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
7、测试环境,制造未提交事务,把程序debug挂起:
再次查看:show PROCESSLIST
执行查询未提交事务语句:select * from information_schema.INNODB_TRX;
SELECT
a.id,a.user,a.host,b.trx_started,b.trx_query
FROM information_schema.processlist a RIGHT OUTER JOIN information_schema.innodb_trx b
ON a.id = b.trx_mysql_thread_id;
如上只是其中一种事务挂起情况,目前的解决方案,就是手动kill掉长期挂起,未提交的事务。
还有其他原因,比如手动开启事务,发生异常的时候没有进行回滚操作,导致事务挂起;
再比如,开启事务以后,强行kill掉程序或者宕机,也会导致事务挂起。
其他情况,欢迎补充;
1、事务过程中执行其他非数据库操作,导致事务长期未被处理。
2、事务处理异常或实现逻辑有误,导致事务未被正常处理。
3、网段异常导致应用端请求未被正常发送给数据库,数据库等待应用后续操作。
4、应用服务器性能问题(如CPU爆满),导致应用无法及时切换到该进程进行处理。
参考帖:https://blog.csdn.net/weixin_39827589/article/details/113489406
MySQL Transaction--查看未提交事务执行的SQL - TeyGao - 博客园