意向锁解决的核心问题是表锁与行锁冲突判断效率低:无意向锁时需全表扫描行锁状态,而IS/IX锁作为表级“预告”,使表锁只需检查一次意向锁即可快速判定是否可加。

意向锁解决的核心问题是表锁和行锁的冲突判断效率
没有意向锁时,LOCK TABLES t WRITE这类语句要加表级排他锁,就得挨个检查表里每一行是否被其他事务加了行锁——大表上可能扫几百万行,直接卡住。意向锁就是 InnoDB 在加行锁前自动打的一个轻量“预告”,只更新表元数据里的锁状态,后续查兼容性只要读一次就能判断。
IS 和 IX 锁分别对应哪些 SQL 操作
你写的 SQL 不会显式触发意向锁,InnoDB 在执行前就悄悄加好了:
-
SELECT ... LOCK IN SHARE MODE→ 自动加IS锁 -
SELECT ... FOR UPDATE、UPDATE、DELETE→ 自动加IX锁 -
INSERT一般不加行锁,但也会加IX锁(唯一键冲突检查需要)
注意:INSERT 不带唯一约束时可能跳过行锁,但 IX 锁照加——它只反映“意图”,不依赖实际是否真锁了某行。
意向锁不参与业务逻辑,但会阻塞表级锁
意向锁本身不拦查询、不拦更新,但它会让 LOCK TABLES t WRITE 或 ALTER TABLE 卡住。因为表级 X 锁与 IS 和 IX 都互斥。只要表上有任意活跃事务在做 FOR UPDATE 或 LOCK IN SHARE MODE,哪怕只锁了一行,LOCK TABLES 就得等。
容易忽略的一点是:SHOW ENGINE INNODB STATUS\G 能看到意向锁,但它不会出现在 information_schema.INNODB_TRX 或锁等待图里——它太轻,只起协调作用,不计入事务锁统计。
锁兼容性决定能否并行执行
意向锁之间基本不互斥:IS 和 IX 可以共存;IS 和 IS 也能共存。真正起冲突的是它们和表级锁的关系:
-
IS兼容S(表级共享锁),但不兼容X -
IX和S、X都不兼容
所以多个只读事务(LOCK IN SHARE MODE)可以同时存在,但只要有一个事务在做 FOR UPDATE,其他想加表级锁的就得排队——这个边界比想象中更敏感,尤其在 DDL 与长事务共存时。


















