事务提交后行锁立即释放,但表锁(如LOCK TABLES)需显式UNLOCK;InnoDB行锁释放与ACID一致,而MDL锁独立于事务,DDL会因活跃事务阻塞。
事务提交后行锁立刻释放,但表锁可能延迟
MySQL 的行级锁(如 SELECT ... FOR UPDATE 或 UPDATE 加的锁)在 COMMIT 或 ROLLBACK 执行完毕后**立即释放**。这是 InnoDB 的默认行为,也是 ACID 中隔离性的基础保障。
但要注意:如果事务中包含隐式或显式的 LOCK TABLES(MyISAM 风格),这类表级锁不会随事务提交释放,必须显式执行 UNLOCK TABLES;InnoDB 一般不走这条路,除非手动切换存储引擎或误用。
- 使用
information_schema.INNODB_TRX和INNODB_LOCKS(MySQL 5.6/5.7)或performance_schema.data_locks(8.0+)可查当前持有锁 - 长事务会持续持锁,哪怕只读未修改——只要用了
SELECT ... FOR UPDATE或SELECT ... LOCK IN SHARE MODE -
AUTOCOMMIT=0下,一个语句不自动提交,锁会一直挂着,直到你敲COMMIT
MySQL 语句执行顺序不是“从上到下”,而是按优化器重排 + 锁获取时机决定
你写的 SQL 顺序 ≠ 实际执行顺序。MySQL 优化器会基于索引、统计信息、成本估算重排执行计划,而加锁动作发生在执行器真正访问某行时,不是解析时。
例如:
UPDATE t1 SET a = 1 WHERE id IN (SELECT id FROM t2 WHERE status = 'pending');
表面看是先查 t2 再更新 t1,但实际可能是先锁定 t1 匹配行(甚至全表扫描加锁),再回表查 t2 过滤——取决于是否能走索引、是否启用 semi-join 优化等。