---
### **一、意向锁的自动性与触发条件**
1. **意向锁的自动性**
InnoDB 存储引擎会 **自动添加意向锁**,无需用户手动干预。但 **并非所有事务都会加意向锁**,只有在以下场景中触发:
• **行级锁操作**:当事务需要给 **某一行数据加共享锁(S)或排他锁(X)** 时,InnoDB 会先自动在表级添加对应的 **意向共享锁(IS)或意向排他锁(IX)**。
• **示例**:
```sql
-- 事务1:给行加 X 锁时,自动添加表级 IX 锁
BEGIN;
SELECT * FROM t WHERE id=1 FOR UPDATE; -- 行级 X 锁 + 表级 IX 锁
COMMIT;
```
2. **无行级锁则不触发**
如果事务 **仅执行普通的 SELECT 查询(不包含 `FOR UPDATE` 或 `LOCK IN SHARE MODE`)**,且隔离级别为 **可重复读(RR)或读已提交(RC)**,则通过 **快照读(MVCC)** 实现一致性,**无需加行级锁**,因此也不会触发意向锁。
---
### **二、意向锁的触发场景**
#### **1. 显式行级锁操作**
• **共享锁(S 锁)**:
使用 `SELECT ... LOCK IN SHARE MODE` 时,事务自动获取表级 IS 锁。
• **排他锁(X 锁)**:
使用 `SELECT ... FOR UPDATE`、`UPDATE`、`DELETE` 时,事务自动获取表级 IX 锁。
#### **2. 隐式行级锁操作**
• **唯一约束冲突**:
插入数据时,若触发唯一索引冲突(如重复主键),InnoDB 会隐式对冲突行加 X 锁,同时自动添加表级 IX 锁。
• **外键约束**:
涉及外键关联的插入或删除操作时,可能触发行级锁及对应的意向锁。
#### **3. 表级锁与意向锁的协调**
• 当其他事务尝试 **加表级锁**(如 `LOCK TABLES ... WRITE`)时,意向锁会触发冲突检查:
◦ 若表已存在 IX 锁,则表级 X 锁需等待 IX 锁释放。
◦ 若表已存在 IS 锁,则表级 S 锁仍可兼容。
---
### **三、意向锁的兼容性与冲突**
| **锁类型** | **IS(意向共享)** | **IX(意向排他)** | **S(表共享)** | **X(表排他)** |
|------------|--------------------|--------------------|-----------------|-----------------|
| **IS** | 兼容 | 兼容 | 兼容 | 冲突 |
| **IX** | 兼容 | 兼容 | 冲突 | 冲突 |
| **S** | 兼容 | 冲突 | 兼容 | 冲突 |
| **X** | 冲突 | 冲突 | 冲突 | 冲突 |
• **关键规则**:
• **IX 与 IX 兼容**:多个事务可同时对同一表声明 IX 锁(如并发更新不同行)。
• **IX 与 X 冲突**:若某事务持有表级 X 锁(如 `ALTER TABLE`),其他事务无法获取 IX 锁。
---
### **四、总结**
1. **何时加意向锁**:
• 仅在事务需要 **行级锁(S/X)** 时自动触发,普通查询(无锁)不涉及。
• 显式锁操作(`FOR UPDATE`)或隐式锁操作(唯一约束、外键)均会触发。
2. **核心价值**:
• **减少锁冲突检查成本**:意向锁通过表级标记,避免逐行检查行锁状态,提升并发性能。
• **协调多粒度锁**:确保表级锁与行级锁的共存逻辑正确性。
**示例场景**:
• 事务 A 更新 `id=1` 的行,触发表级 IX 锁;事务 B 更新 `id=2` 的行,同样触发 IX 锁,两者兼容,可并发执行。
• 事务 C 执行 `ALTER TABLE` 需要表级 X 锁,此时会阻塞等待所有 IX 锁释放。
下一篇:mysql驱动表与被驱动表
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传