InnoDB如何解决幻读的

InnoDB 使用一种称为 Next-Key Locking 的锁机制来解决幻读问题。幻读发生在一个事务在读取某个范围内的记录时,另一个事务在这个范围内插入新的记录。InnoDB 的 Next-Key Locking 结合了行锁(Row Lock)和间隙锁(Gap Lock),确保在执行范围查询时能够锁定现有记录以及它们之间的间隙,从而防止其他事务在该范围内插入新的记录。

Next-Key Locking 机制

Next-Key Locking 是一种在索引记录上应用的锁机制,它锁住的并不仅仅是索引记录本身,还包括索引记录之间的间隙。这种机制可以防止其他事务在锁定的范围内插入新的记录。

具体例子

假设你有一个包含以下记录的表 employees

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

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

在使用可重复读(REPEATABLE READ)隔离级别时,InnoDB 如何避免幻读?考虑以下两个事务:

  • 事务 A:执行一个范围查询。
  • 事务 B:在事务 A 的范围内插入新的记录。
事务 A
sql 复制代码
START TRANSACTION;
SELECT * FROM employees WHERE id BETWEEN 1 AND 5;

当事务 A 执行上述查询时,InnoDB 会对满足条件的所有记录(id=1, id=3, id=5)以及这些记录之间的间隙((1,3), (3,5), (5,∞))加锁。

事务 B
sql 复制代码
START TRANSACTION;
INSERT INTO employees (id, name) VALUES (2, 'David');

由于事务 A 已经锁定了 id 范围 [1,5] 及其间隙,所以事务 B 尝试在范围 [1,3] 的间隙中插入 id=2 的新记录时会被阻塞,直到事务 A 提交或回滚。

示例演示

创建表和插入数据
sql 复制代码
CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

INSERT INTO employees (id, name) VALUES (1, 'Alice'), (3, 'Bob'), (5, 'Charlie');
事务 A
sql 复制代码
START TRANSACTION;
SELECT * FROM employees WHERE id BETWEEN 1 AND 5; -- Next-Key Locking 在索引记录及其间隙上加锁
事务 B
sql 复制代码
START TRANSACTION;
INSERT INTO employees (id, name) VALUES (2, 'David'); -- 此操作会被阻塞,直到事务 A 提交或回滚
提交事务 A
sql 复制代码
COMMIT; -- 提交事务 A 后,事务 B 可以继续执行

总结

InnoDB 使用 Next-Key Locking 机制通过结合行锁和间隙锁来解决幻读问题。当一个事务在执行范围查询时,InnoDB 会锁定查询结果集中的每一条记录以及这些记录之间的间隙。这确保了在范围内的任何插入操作都被阻塞,从而避免了幻读。

这种锁机制在可重复读(REPEATABLE READ)隔离级别下有效地避免了幻读,使得事务在读取范围内的数据时,不会因为其他事务的插入而读取到新的"幻影"记录。

相关推荐
倔强的石头_12 小时前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
jiayou642 天前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
李广坤3 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
爱可生开源社区4 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1774 天前
《从零搭建NestJS项目》
数据库·typescript
加号34 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏4 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐4 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再4 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip
tryCbest4 天前
数据库SQL学习
数据库·sql