关于数据库mysql死锁:MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
现场:
om.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_181]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_181]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_181]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_181]
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
at com.mysql.jdbc.Util.getInstance(Util.java:387) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:946) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
解决方案
1. 运行以下命令,查找提交事务的数据,杀掉线程即可解决
select * from information_schema.innodb_trx
kill thread_id;
2. 增加锁等待时间,即增大下面配置项参数值,单位为秒(s)
3. innodb_lock_wait_timeout=500
3、优化存储过程,事务避免过长时间的等待。
可以用下面三张表来查原因-information_schema:
innodb_trx ## 当前运行的所有事务
innodb_locks ## 当前出现的锁
innodb_lock_waits ## 锁等待的对应关系
其他:
1、开始事务(使用@transtion)必须指定超时时间
@Transactional( rollbackFor = Exception.class , isolation = Isolation.REPEATABLE_READ, timeout = 30)
2、事务中 存在批量修改、删除的语句的时候,where 条件尽量加索引
3、事务中 存在批量修改、删除数据时,尽可能减少事务的执行时间