数据库的意向锁

数据库的意向锁

1. 什么是意向锁

意向锁(Intention Lock) 是 表级锁,用来表示一个事务接下来打算在某些行上加共享锁(S锁)或排他锁(X锁)。

它本身不会直接锁住数据行,而是为了协调行锁与表锁的共存,帮助数据库快速判断表级锁是否与当前行锁冲突。

核心作用:锁兼容性检测的优化,避免在加表锁时逐行检查。

2. 为什么需要意向锁

如果没有意向锁,假设有事务在表的部分行上加了行级锁,而另一个事务想要加表级锁,数据库必须逐行扫描检查是否有锁冲突,这样开销巨大。

有了意向锁:

事务在加行锁前,先在表上加一个对应的意向锁。

当其他事务申请表锁时,只需先检查表级的意向锁,就能快速判断是否会冲突,省掉逐行检查。

3. 意向锁的类型

InnoDB 中有两种意向锁:

IS(Intention Shared Lock,意向共享锁)

表示事务打算在某些行上加共享锁(S锁)。

IX(Intention Exclusive Lock,意向排他锁)

表示事务打算在某些行上加排他锁(X锁)。

4. 意向锁的特点

粒度:表级

加锁时机:

事务在加行级 S 锁前,会先加 IS 锁

事务在加行级 X 锁前,会先加 IX 锁

不会阻塞行级操作,它的目的是和其他表级锁配合。

不会直接造成死锁,因为它只是一个标记锁。

5. 锁兼容性(MySQL InnoDB)

IS

IX

S

X

IS

IX

S

X

✅ 表示两个锁可以共存

❌ 表示两个锁冲突

6. 举例

假设有一张 account 表,事务 T1 想修改 id=1 的记录:

BEGIN;

UPDATE account SET balance = balance + 100 WHERE id = 1;

流程:

InnoDB 在 account 表上加 IX 锁(表示我要在某行加排他锁)。

在 id=1 这行加行级 X 锁。

现在事务 T2 想加表级 S 锁:

LOCK TABLE account READ;

T2 检查表上已有 IX 锁 → 与 S 锁冲突 → 阻塞。

无需去逐行检查。

7. 总结口诀

行锁之前先表锁(意向锁)

IS 表示“我要加行S锁”

IX 表示“我要加行X锁”

表锁检查时先看意向锁,不用逐行查