MySQL事务锁超时后不会自动回滚,仅中断当前语句并抛出错误,事务仍处于活动状态,需应用层显式执行ROLLBACK或COMMIT;否则继续操作将引发新错误或数据不一致。

不会自动中断执行,但执行完后行为取决于事务状态和连接是否被服务端感知到已断开。
MySQL 服务端根本不知道客户端已经断开了
TCP 连接异常中断(比如网线拔掉、进程 kill -9、客户端机器宕机)时,服务端 socket 状态仍为 ESTABLISHED,MySQL 不会立刻收到 FIN 包,也就无法触发连接清理逻辑。它会继续执行当前 SQL,哪怕客户端早已消失。
- 执行期间:服务端完全无感知,照常扫描索引、加锁、写 undo log
- 执行完成那一刻:才可能发现写结果回客户端失败(比如
send()返回 -1 或 EPIPE),此时才会触发后续处理 - 常见错误日志片段:
Lost connection to MySQL server during query或MySQL server has gone away
SQL 执行完后,事务是否回滚?关键看 autocommit 和提交状态
回滚与否不是“服务端主动判断要不要回滚”,而是由连接关闭时的事务上下文决定:
- 如果
autocommit = 0,且该 SQL 属于一个未提交的事务(即之前有BEGIN或隐式开启,但还没COMMIT),服务端在确认连接丢失后会执行trans_rollback_stmt()—— 回滚整个事务 - 如果
autocommit = 1,每条 DML 都是独立事务,执行完就已提交,断开不影响结果 - 如果是 DDL(如
CREATE TABLE),语句执行完立即隐式提交,断开也无回滚可言 - 如果事务中已有部分语句提交(比如中间执行了
COMMIT),那么只回滚COMMIT之后的未提交部分(实际极少这么用,风险高)
wait_timeout 超时断连 vs 网络静默中断,处理逻辑不同
两种“断开”在服务端眼里是不同事件:
-
wait_timeout或interactive_timeout超时(默认 28800 秒):服务端主动调用kill_connection(),会立即终止会话并回滚未提交事务 - 网络静默中断(无 FIN):服务端靠后续 I/O 操作失败才发现,回滚发生在 SQL 执行完毕、尝试返回结果时;若 SQL 执行本身耗时极长(比如大表
UPDATE),回滚动作会被延迟到那时才启动 - 注意:
KILL CONNECTION <id>效果等同于超时,立即回滚;KILL QUERY <id>只中断当前语句,事务保持打开,连接不关闭
真正容易被忽略的是回滚本身也可能卡住
事务修改了上万行数据,断开后触发回滚,InnoDB 必须重放 undo log 来撤销变更——这个过程是同步、单线程、不可中断的。它会占用该连接线程,期间:
- 你查
INFORMATION_SCHEMA.INNODB_TRX仍能看到TRX_STATE = 'ROLLING BACK' - 其他请求无法复用这个线程,也无法 kill 掉正在回滚的操作(
KILL对它无效) - 回滚时间可能远超原 SQL 执行时间,尤其涉及 BLOB 或二级索引更新时


















