mysql事务回滚会释放锁吗_mysql锁释放机制说明

8次阅读

会释放,但不是立刻无条件释放——ROLLBACK执行完成时,事务持有的所有行锁、表锁(含意向锁)才统一清理;锁生命周期严格绑定事务,事务结束即释放。

mysql事务回滚会释放锁吗_mysql锁释放机制说明

事务回滚时锁是否释放?

会释放,但不是“立刻无条件释放”——ROLLBACK 执行完成的那一刻,该事务持有的所有行锁、表锁(含意向锁)才会被统一清理。这是 InnoDB 的硬性规则:锁的生命周期严格绑定事务生命周期,事务结束(无论 COMMIT 还是 ROLLBACK),锁就释放。

为什么有时感觉“回滚后还卡着”?

常见错觉来源有三个:

  • 你执行了 ROLLBACK,但没确认事务真正结束了——比如客户端连接没关闭、autocommit=0 且后续没显式开启新事务,导致会话仍处于“隐式事务未提交”状态;
  • 锁被其他**未结束的事务**持有,和你的回滚无关。例如事务 A 正在等事务 B 释放某行锁,B 回滚了,A 却因自身逻辑卡住没继续执行,看起来像“锁还在”;
  • READ-COMMITTEDREAD-UNCOMMITTED 隔离级别下,InnoDB 对不匹配 WHERE 条件的扫描行会**提前释放行锁**,但这和回滚无关,是查询过程中的动态释放行为。

不同隔离级别对锁释放时间有影响吗?

有,但只影响“加锁期间”的行为,不影响回滚时刻的释放逻辑:

  • REPEATABLE-READSERIALIZABLE:所有加的行锁/表锁,一律等到事务结束(COMMITROLLBACK)才释放;
  • READ-COMMITTED:普通 select 不加锁(快照读),但 UPDATE/delete 仍加行锁,且只锁住最终命中的记录(不匹配的扫描行会边扫边放);
  • READ-UNCOMMITTED:几乎不加锁,自然也谈不上“回滚释放”——但这个级别极少用于生产。

注意:ROLLBACK 本身不会改变锁的释放时机,它只是“触发事务结束”的动作之一。

如何验证锁是否真被释放了?

别靠猜,用 mysql 自带视图查:

  • 查当前阻塞关系:
    SELECT * FROM information_schema.INNODB_TRX;

    trx_state 是否为 ROLLING BACK 或已消失;

  • 查锁等待链:
    SELECT * FROM information_schema.INNODB_LOCK_WaiTS;

    如果为空,说明没有活跃等待;

  • 查锁本身:
    SELECT * FROM performance_schema.data_locks;

    (MySQL 8.0+)或老版本用 SHOW ENGINE INNODB STATUSG 中的 TRANSACTIONS 部分。

最容易被忽略的是:锁释放不等于事务彻底退出。如果应用层没关闭连接、或者用了连接池且连接被复用,旧事务上下文可能残留——务必确认 INNODB_TRX 中对应 trx_id 已消失,才算真正干净。

text=ZqhQzanResources