MySQL特定记录更新查询无响应并抛出1205错误求助
解决MySQL Update语句锁超时(1205错误)的问题
首先,你遇到的1205错误全称是**Lock wait timeout exceeded; try restarting transaction**,本质是你的更新请求等待行锁的时间超过了MySQL的默认超时阈值(通常是50秒)——StatusID=4的行刚好被其他事务占用了锁,而StatusID=5的行没有锁冲突,所以能正常更新。下面是一步步的排查和解决方法:
一、先定位谁锁住了StatusID=4的行
执行以下命令查看当前InnoDB的事务和锁状态:
- 查看所有正在运行的事务:
重点关注SELECT trx_id, trx_started, trx_mysql_thread_id, trx_query FROM INFORMATION_SCHEMA.INNODB_TRX;trx_started字段,如果有事务启动后很久没提交,那它大概率就是占用锁的“元凶”。 - 查看当前锁的详细信息(旧版本MySQL适用,新版本可查
performance_schema相关表):
找到关联StatusID=4的锁记录,对应的SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;lock_trx_id就是占用锁的事务ID。
二、释放占用锁的事务
如果找到了卡住的事务,直接杀掉对应的线程即可:
KILL [trx_mysql_thread_id];
把[trx_mysql_thread_id]替换成你从INNODB_TRX里查到的线程ID,之后重新执行update语句,应该就能成功了。
三、排查锁冲突的根源
- 检查未提交的长事务:比如调试代码时打开了事务但没提交,或者程序事务逻辑有bug,导致事务一直处于活跃状态。
- 确认索引有效性:你的
where StatusID = '4'中,StatusID字段有没有加索引?如果没有索引,MySQL会做全表扫描,可能扩大锁范围;建议给StatusID加索引避免后续问题:CREATE INDEX idx_order_status_statusid ON catalog.order_status(StatusID); - 检查字段类型匹配:你用了字符串格式的
'4',那表中StatusID字段是VARCHAR还是INT?如果是INT类型,这里的字符串会触发隐式转换,导致索引失效,可能扩大锁范围——建议保持类型一致,比如用StatusID = 4(若字段是INT)。 - 排查其他业务操作:有没有定时任务、后台程序或其他用户正在修改StatusID=4的记录?比如其他程序读取这条记录时加了排他锁,或者正在执行更新操作。
四、临时应急方案
如果紧急需要更新这条记录,可以临时调整锁等待超时时间,再执行更新(但优先推荐先释放锁):
SET SESSION innodb_lock_wait_timeout = 100; -- 临时将超时时间设为100秒 START TRANSACTION; UPDATE `catalog`.`order_status` SET `Status` = 'CONFIRMED' WHERE `StatusID` = '4'; COMMIT;
内容的提问来源于stack exchange,提问作者Suresh AK
相关产品推荐
相关产品推荐

