MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction

遇到 MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction 这个错误时,通常意味着你的数据库事务在尝试获取一个锁时等待了太长时间。这通常发生在有长时间运行的事务持有锁,而其他事务在等待这个锁时超过了锁等待超时的时间。要解决这个问题,你可以按照以下步骤进行排查和解决

1. 确定哪个事务持有锁

首先,需要找出哪个事务持有了锁并导致其他事务等待。你可以通过运行以下SQL命令来查看当前的锁情况:

 

sql

SHOW ENGINE INNODB STATUS;

这个命令会显示InnoDB的许多内部运行信息,包括锁等待和死锁信息。在输出的 LATEST DETECTED DEADLOCK 部分,你可以找到有关最近检测到的死锁的信息。在 TRANSACTIONS 部分,你可以看到当前正在运行的事务及其锁定状态。

2. 分析长时间运行的查询

通过分析长时间运行的查询,你可以确定是哪些查询可能导致了锁等待超时。运行以下命令查看长时间运行的事务:

sql

SELECT * FROM information_schema.innodb_trx ORDER BY trx_started;

这将列出当前运行的所有InnoDB事务及其开始时间。

3. 终止长时间运行的事务

如果确定某个事务是导致锁等待超时的原因,且该事务是可以安全中断的,你可以通过杀死该事务来释放其持有的锁

执行 sql  KILL 线程 ID;

线程id也就是步骤2 查出来的trx_mysql_thread_id;

4.调整等待时间

SET GLOBAL innodb_lock_wait_timeout = 120; -- 全局设置

SET SESSION innodb_lock_wait_timeout = 120; -- 当前会话设置