基础环境设置
CREATE TABLE test_gap (
id INT PRIMARY KEY,
value INT,
name VARCHAR(50),
INDEX idx_value (value)
) ENGINE=InnoDB;
INSERT INTO test_gap VALUES
(1, 10, 'A'),
(3, 20, 'B'),
(5, 30, 'C'),
(7, 40, 'D'),
(9, 50, 'E');
一、等值查询的间隙锁
1.1 查询不存在的值
查询SQL |
锁定范围 |
说明 |
SELECT * FROM test_gap WHERE value = 15 FOR UPDATE; |
(10, 20) |
15位于10和20之间 |
SELECT * FROM test_gap WHERE value = 25 FOR UPDATE; |
(20, 30) |
25位于20和30之间 |
SELECT * FROM test_gap WHERE value = 5 FOR UPDATE; |
(-∞, 10) |
5小于最小值10 |
SELECT * FROM test_gap WHERE value = 60 FOR UPDATE; |
(50, +∞) |
60大于最大值50 |
1.2 查询存在的值
查询SQL |
锁类型 |
说明 |
SELECT * FROM test_gap WHERE value = 20 FOR UPDATE; |
临键锁 |
记录锁+前后间隙锁 |
SELECT * FROM test_gap WHERE id = 3 FOR UPDATE; |
记录锁 |
主键查询,无间隙锁 |
二、范围查询的间隙锁
2.1 闭区间范围查询
查询SQL |
具体锁定区间 |
WHERE value >= 20 AND value <= 40 |
(10, 20] + (20, 30] + (30, 40] + (40, 50) |
WHERE value >= 15 AND value <= 35 |
(10, 20] + (20, 30] + (30, 40) |
WHERE value >= 25 AND value <= 45 |
(20, 30] + (30, 40] + (40, 50) |
2.2 开区间范围查询
查询SQL |
具体锁定区间 |
WHERE value > 20 AND value < 40 |
(20, 30] + (30, 40) |
WHERE value > 15 AND value < 35 |
(10, 20] + (20, 30] + (30, 40) |
WHERE value > 25 AND value < 45 |
(20, 30] + (30, 40] + (40, 50) |
2.3 单边界范围查询
查询SQL |
锁定范围 |
WHERE value >= 30 |
(20, 30] + (30, 40] + (40, 50] + (50, +∞) |
WHERE value > 30 |
(30, 40] + (40, 50] + (50, +∞) |
WHERE value <= 30 |
(-∞, 10] + (10, 20] + (20, 30] + (30, 40) |
WHERE value < 30 |
(-∞, 10] + (10, 20] + (20, 30) |
三、特殊情况的间隙锁
3.1 空表的间隙锁
查询SQL |
锁定范围 |
说明 |
SELECT * FROM empty_table WHERE value = 100 FOR UPDATE; |
(-∞, +∞) |
整个值域间隙 |
SELECT * FROM empty_table WHERE value > 50 FOR UPDATE; |
(-∞, +∞) |
整个值域间隙 |
3.2 只有一条记录的表
查询SQL |
锁定范围 |
说明 |
WHERE value = 50 |
(-∞, 100) |
50不存在,锁定前间隙 |
WHERE value = 150 |
(100, +∞) |
150不存在,锁定后间隙 |
WHERE value = 100 |
(-∞, 100] + (100, +∞) |
存在,临键锁覆盖所有间隙 |
四、锁定范围的边界规则总结
规则 |
说明 |
示例 |
记录存在 |
加临键锁 = 记录锁 + 间隙锁 |
value=20 → (10,20] + (20,30) |
记录不存在 |
只加间隙锁 |
value=25 → (20,30) |
范围查询 |
锁定所有可能插入影响结果的间隙 |
value>20 → (20,30] + (30,40] + ... |
边界保护 |
查询边界外也要锁定相邻间隙 |
20≤value≤40 → 还要锁(40,50) |