InnoDB 支持 多粒度锁,它允许 行级锁 与 表级锁 共存,而意向锁就是其中的一种 表锁。
意向锁有什么作用?
如果需要用到表锁的话,如何判断表中的记录没有行锁呢,一行一行遍历肯定是不行,性能太差。我们需要用到一个叫做意向锁的东东来快速判断是否可以对某个表使用表锁。
意向锁分为两种
- 意向共享锁(intention shared lock, IS):事务有意向对表中的某些行加共享锁(S 锁)
SELECT column FROM table ... LOCK IN SHARE MODE;
- 意向排他锁(intention exclusive lock, IX):事务有意向对表中的某些行加排他锁(X 锁)
SELECT column FROM table ... FOR UPDATE;
即:意向锁是由 存储引擎自己维护 的,用户无法手动操作意向锁,在为数据行加共享 / 排他锁之前, InooDB 会先获取该数据行 所在数据表的对应意向锁。
意向锁的并发性
意向锁不会与行级的共享 / 排他锁互斥!正因为如此,意向锁并不会影响到多个事务对不同数据行加排他锁时的并发性。(不然我们直接用普通的表锁就行了)
意向锁之间是互相兼容的。
| IS 锁 | IX 锁 | |
|---|---|---|
| IS 锁 | 兼容 | 兼容 |
| IX 锁 | 兼容 | 兼容 |
意向锁和共享锁和排它锁互斥(这里指的是表级别的共享锁和排他锁,意向锁不会与行级的共享锁和排他锁互斥)。
| IS 锁 | IX 锁 | |
|---|---|---|
| S 锁 | 兼容 | 互斥 |
| X 锁 | 互斥 | 互斥 |
总结
从上面的案例可以得到如下结论:
- InnoDB 支持多粒度锁,特定场景下,行级锁可以与表级锁共存。
- 意向锁之间互不排斥,但除了 IS 与 S 兼容外,意向锁会与共享锁 / 排他锁互斥。
- IX,IS 是表级锁,不会和行级的 X,S 锁发生冲突。只会和表级的 X,S 发生冲突。
- 意向锁在保证并发性的前提下,实现了行锁和表锁共存且满足事务隔离性的要求。