SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction
在PHP调试时 提交事务触发异常后没有执行回滚导致mysql死锁,以致后续请求更新不了数据
问题原因
在mysql中事务a执行修改数据,比如: update table set a=1 where id=1;此时事务并未进行提交也没有回滚,然后事务B开始运行,修改同一条数据: update table set a=2 where id=1;
此时b一直等待a释放锁直到超时,超过设置的超时时间后会产生报错
问题出现环境:
1、在同一事务内先后对同一条数据进行插入和更新操作;
2、多台服务器操作同一数据库;
3、瞬时出现高并发现象;
4、语句中没有执行commit,也没有rollback就return退出了
比如参数检查不通过,直接return错误信息,导致回滚不能执行
如以下代码先执行了更新操作,后面出错又直接返回,导致没有执行rollback,对于这种操作return前一点要回滚,或者抛出异常统一扑捉后返回错误信息
$this->startTrans();
try {
$user = new User();
$user->where('id',$userId)->update(['realname'=>$parentName]);
$existId = $this->where('class_id',$classId)->where('student_number',$number)->find();
if ($existId)
return ['data' => '', 'code' => 300, 'msg' => '学号重复'];
$this->commit();
} catch (Throwable $e) {
$this->rollback();
return ['data' => '', 'code' => 20102, 'msg' => $e->getMessage()];
}
异常信息
SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction
解决
1、通过下面语句查找到为提交事务的数据,kill此线程即可。
select * from information_schema.innodb_trx
trx_mysql_thread_id 即为该进程
kill 1544
相关排查语句
show full processlist ## 当前连接的线程
select * from information_schema.innodb_trx ## 当前运行的所有事务
select * from information_schema.innodb_locks ## 当前出现的锁
select * from information_schema.innodb_lock_waits ## 锁等待的对应关系
字段详细信息
desc information_schema.innodb_locks;
Field Type Null Key Default Remark
lock_id varchar(81) NO 锁ID
lock_trx_id varchar(18) NO 拥有锁的事务ID
lock_mode varchar(32) NO 锁模式
lock_type varchar(32) NO 锁类型
lock_table varchar(1024) NO 被锁的表
lock_index varchar(1024) YES NULL 被锁的索引
lock_space bigint(21) unsigned YES NULL 被锁的表空间号
lock_page bigint(21) unsigned YES NULL 被锁的页号
lock_rec bigint(21) unsigned YES NULL 被锁的记录号
lock_data varchar(8192) YES NULL 被锁的数据
desc information_schema.innodb_lock_waits
Field Type Null Key Default Remark
requesting_trx_id varchar(18) NO 请求锁的事务ID
requested_lock_id varchar(81) NO 请求锁的锁ID
blocking_trx_id varchar(18) NO 当前拥有锁的事务ID
blocking_lock_id varchar(81) NO 当前拥有锁的锁ID
desc information_schema.innodb_trx ;
Field Type Null Key Default Extra Remark
trx_id varchar(18) NO 事务ID
trx_state varchar(13) NO 事务状态:
trx_started datetime NO 0000-00-00 00:00:00 事务开始时间;
trx_requested_lock_id varchar(81) YES NULL innodb_locks.lock_id
trx_wait_started datetime YES NULL 事务开始等待的时间
trx_weight bigint(21) unsigned NO 0 #
trx_mysql_thread_id bigint(21) unsigned NO 0 事务线程ID
trx_query varchar(1024) YES NULL 具体SQL语句
trx_operation_state varchar(64) YES NULL 事务当前操作状态
trx_tables_in_use bigint(21) unsigned NO 0 事务中有多少个表被使用
trx_tables_locked bigint(21) unsigned NO 0 事务拥有多少个锁
trx_lock_structs bigint(21) unsigned NO 0 #
trx_lock_memory_bytes bigint(21) unsigned NO 0 事务锁住的内存大小(B)
trx_rows_locked bigint(21) unsigned NO 0 事务锁住的行数
trx_rows_modified bigint(21) unsigned NO 0 事务更改的行数
trx_concurrency_tickets bigint(21) unsigned NO 0 事务并发票数
trx_isolation_level varchar(16) NO 事务隔离级别
trx_unique_checks int(1) NO 0 是否唯一性检查
trx_foreign_key_checks int(1) NO 0 是否外键检查
trx_last_foreign_key_error varchar(256) YES NULL 最后的外键错误
trx_adaptive_hash_latched int(1) NO 0 #
trx_adaptive_hash_timeout bigint(21) unsigned NO 0 #3