赞
踩
执行sql: (userId 是主键)
INSERT INTO USER (USERID,USERNAME,AGE)
VALUES(1000,'TEST',20);
异常:
com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
; SQL []; Lock wait timeout exceeded; try restarting transaction; nested exception is
com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
原因分析: 在MySQL中已经有一条事务在执行userId = 100 的insert操作,但是一直都没有提交。导致再次插入一条userId = 100 的记录时,就会发生第一次行锁一直不释放,后面再插入或者更新的时候,SQL执行就一直等待,超时就会报出上述错误。
排查方法:
1,查看执行中的事务:
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX ;
2,当前出现的锁
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
3,锁等待的对应关系
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
4,显示当前处理的线程信息
SHOW PROCESSLIST;
5,杀掉事务
KILL 事务线程ID
6,如果像5截图中,trx_query 的内容是空的,不能定位到问题
重现问题,再次执行sql,立马执行
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
出发现有两条,S:读锁/共享锁 X:写锁/独占锁
如果想了解 lock_type,loca_mode 可以参考:https://blog.csdn.net/u014710633/article/details/90486467
第一次锁的情况:
然后再重复一次sql, 第二次锁的情况:
对比第一次,第二次锁的lock_trx_id .两次都出现的表示目前正在锁死的lock_trx_id:143984406
然后到INFORMATION_SCHEMA.INNODB_TRX中找到对应的事务线程ID
SELECT TRX_MYSQL_THREAD_ID FROM INFORMATION_SCHEMA.INNODB_TRX WHERE LOCK_ID ='143984406' ;
执行 KILL TRX_MYSQL_THREAD_ID;
最后再测试一次:
INSERT INTO USER (USERID,USERNAME,AGE)
VALUES(1000,'TEST',20);
执行成功就说明解决了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。