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

来源:这里教程网 时间:2026-02-28 20:46:19 作者:

事务回滚时锁是否释放?

会释放,但不是“立刻无条件释放”——

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

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

常见错觉来源有三个:

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

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

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

REPEATABLE-READ
SERIALIZABLE
:所有加的行锁/表锁,一律等到事务结束(
COMMIT
ROLLBACK
)才释放;
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 STATUS\G
中的
TRANSACTIONS
部分。

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

INNODB_TRX
中对应
trx_id
已消失,才算真正干净。

相关推荐