详解MySQL的间隙锁

MySQL 的间隙锁(Gap Lock)

间隙锁(Gap Lock)是 InnoDB 存储引擎中的一种锁机制,用于防止幻读现象。幻读是指在一个事务中,两次读取同一个范围的数据时,第二次读取出现了第一次没有出现的数据行。间隙锁通过锁定一个范围内的"间隙"来防止其他事务在该范围内插入新记录,从而避免幻读。

间隙锁的特性

锁定范围 :间隙锁锁定的是记录之间的间隙,而不是具体的记录。例如,如果表中有记录 1, 2, 4, 5,那么间隙锁可能锁定 (2, 4) 之间的间隙。

防止插入 :间隙锁可以防止其他事务在锁定的间隙范围内插入新记录。例如,如果间隙 (2, 4) 被锁定,则不能在 24 之间插入新的记录。

共享锁:间隙锁是共享锁,多个事务可以同时持有同一个间隙锁,但这些事务都不能在该间隙范围内插入新记录。

间隙锁的使用场景

间隙锁通常在以下场景中使用:

  1. 范围查询 :在执行范围查询时,例如 SELECT * FROM table WHERE column BETWEEN value1 AND value2 FOR UPDATE,InnoDB 会使用间隙锁来锁定查询范围内的间隙。
  2. 范围删除 :在执行范围删除时,例如 DELETE FROM table WHERE column BETWEEN value1 AND value2,InnoDB 也会使用间隙锁来锁定删除范围内的间隙。

示例

假设我们有一个表 employees,其中包含以下记录:

sql 复制代码
CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

INSERT INTO employees (id, name) VALUES (1, 'Alice'), (2, 'Bob'), (4, 'Charlie'), (5, 'David');

在一个事务中执行范围查询并加锁:

sql 复制代码
START TRANSACTION;
SELECT * FROM employees WHERE id BETWEEN 2 AND 4 FOR UPDATE;

此时,InnoDB 会锁定 (2, 4) 之间的间隙,防止其他事务在该范围内插入新记录。

在另一个事务中尝试插入新记录:

sql 复制代码
START TRANSACTION;
INSERT INTO employees (id, name) VALUES (3, 'Eve');

由于 (2, 4) 的间隙被锁定,第二个事务会被阻塞,直到第一个事务提交或回滚。

事务隔离级别与间隙锁

间隙锁在 MySQL 的 REPEATABLE READSERIALIZABLE 隔离级别下生效。在 READ COMMITTEDREAD UNCOMMITTED 隔离级别下,间隙锁通常不会被使用。

总结

间隙锁是 InnoDB 用于防止幻读的一种锁机制,通过锁定记录之间的间隙,防止其他事务在该范围内插入新记录。间隙锁在范围查询和范围删除操作中尤为重要,确保了事务的一致性和隔离性。在实际应用中,理解和正确使用间隙锁可以帮助开发者构建更加健壮和可靠的数据库应用。

相关推荐
jiayou6412 小时前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
于眠牧北13 小时前
MySQL的锁类型,表锁,行锁,MVCC中所使用的临键锁
mysql
李广坤1 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
Turnip12022 天前
深度解析:为什么简单的数据库"写操作"会在 MySQL 中卡住?
后端·mysql
爱可生开源社区2 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1773 天前
《从零搭建NestJS项目》
数据库·typescript
加号33 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏3 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐3 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再3 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip