IS/IX锁是表级意向锁,用于加速表锁判断,不阻塞行操作,仅协调行锁与表锁冲突;其生效前提为查询走索引,否则退化为全表锁,且不可手动添加。

IS/IX锁本质是“一次判断”的加速器
它们存在的全部价值,就是让表级锁(S、X)的获取从“遍历所有行”降为“查一次表元数据”。没有IS/IX时,事务B想对整张表加X锁,必须逐行检查是否已被其他事务加了行级X或S锁——这在千万级表上不可接受。有了IS/IX,InnoDB只需在show engine innodb status\G的TABLE LOCK段里看一眼:有IS或IX记录,就立刻拒绝;没有,直接通过。
IS/IX本身不拦人,只起协调作用
IS和IX都是表级锁,但它们自己不阻止任何行操作,也不锁定任何数据。它们只是“告示牌”:
-
IS表示:“我接下来要给某些行加S锁” -
IX表示:“我接下来要给某些行加X锁” - IS与IX之间完全兼容,不会互相阻塞
- 真正冲突的是
ISvsX、IXvsS、IXvsX——这些才是表级锁层面的互斥逻辑
索引缺失会让IS/IX彻底失效
这是最容易被忽略的实战陷阱:IS/IX只在InnoDB真正使用行锁时才起作用。一旦SELECT ... FOR UPDATE或UPDATE的WHERE条件没走索引(比如对name字段查询但该字段无索引),InnoDB会直接升级为全表X锁——此时你看到的不再是IX,而是真实的表级X锁,IS/IX机制完全绕过。
所以排查锁问题的第一步永远是:EXPLAIN确认执行计划是否命中索引。否则讨论IS/IX的兼容性毫无意义。
你无法手动加IS或IX锁
IS和IX由InnoDB在加行锁前自动申请,用户不能用SQL显式获取。常见误解是以为LOCK IN SHARE MODE会“加IS”,其实它触发的是“先隐式加IS,再加行级S锁”这一连串动作。试图用LOCK TABLES ... READ或WRITE去模拟,得到的是真正的表级S或X锁,和意向锁无关。
真正需要你干预的,只有两件事:确保查询条件能走索引、理解show engine innodb status\G中TABLE LOCK段的真实含义——那里出现IX,说明有事务正在(或即将)修改行;出现X,说明整张表已被锁死。


















