欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

mysql事务和锁超时异常lock wailt timeout exceeded

程序员文章站 2024-01-14 09:20:28
...

当两个事务中,都会同一行记录进行操作的时候,可能会触发死锁,最终抛出超时异常

验证如下
首先在当前的数据库连接会话中
将数据库事务设置为手动提交

set @@autocommit=0;
SHOW VARIABLES like ‘%autocommit%’

然后在当前会话中
执行, 但先不commit
mysql事务和锁超时异常lock wailt timeout exceeded
这个时候在该会话中,事务还没提交

此时在该会话中去查询
mysql事务和锁超时异常lock wailt timeout exceeded
数据已经看不到了。
mysql事务和锁超时异常lock wailt timeout exceeded

但是此时在另一个会话中 ,数据还在,因为之前那个会话的事务没有提交
mysql事务和锁超时异常lock wailt timeout exceeded

如果在另一个会话中,也对这行记录进行操作
mysql事务和锁超时异常lock wailt timeout exceeded

因为会话1的事务没有提交,且在会话1中对记录为aaa的行进行了加锁
此时会话2也去对记录为aaa的行进行删除,需要去等待会话1将锁释放。
但是等待时间在SHOW VARIABLES LIKE ‘innodb_lock_wait_timeout’; 可以看到 是50秒
超出这个时间就会抛出异常 lock wailt timeout exceeded
mysql事务和锁超时异常lock wailt timeout exceeded

因此,最好不要在代码中有特别耗时的大事务,除了容易造成获取锁超时,也容易死锁。

比如说同时在会话1中(操作行1 , 操作行2) ,在会话2中(操作行2,操作行1),彼此等待对方释放X锁。

一些用于查看数据库状态的sql

-- 当前运行的所有事务
select * from information_schema.INNODB_TRX
--  如果发现有超长时间的慢sql  用 kill trx_mysql_thread_id,然后在查询中kill掉就行 

show engine innodb status
-- 显示是自动提交还是手动
show variables like 'autocommit'
-- 查看当前数据库进程
show PROCESSLIST

-- 查询当前会话等待事务锁超时时间 默认是50秒:	
SHOW VARIABLES LIKE 'innodb_lock_wait_timeout';

-- 查询innodb锁
SELECT * FROM information_schema.INNODB_LOCKs;

-- 查询在等待锁的sql
select * from information_schema.INNODB_LOCK_WAITS
相关标签: mysql