MySQL的可重复读事务隔离级别的实现原理

在MySQL中,可重复读事务隔离级别主要是通过MVCC(多版本并发控制)和锁机制来实现的。

MVCC机制

  • 生成Read View:事务开始时,会生成一个Read View,它记录了当前系统中活跃事务的ID列表、最小活跃事务ID和最大事务ID。

  • 数据版本判断:在读取数据时,根据数据行的 DB_TRX_ID 与Read View进行比较,若 DB_TRX_ID 小于最小活跃事务ID,数据对当前事务可见;若大于最大事务ID,不可见;若在活跃事务ID范围内,且不在活跃事务列表中,则可见。以此确保事务在整个生命周期内看到的数据版本是一致的。

锁机制

  • 行锁:对于并发的写操作,MySQL会使用行锁来确保同一时刻只有一个事务能修改某一行数据,避免数据冲突。

  • Next - Key Lock:在InnoDB存储引擎中,还使用Next - Key Lock来防止幻读。它会锁定一个范围,包括索引记录本身和相邻的间隙,阻止其他事务在该范围内插入新记录。

通过MVCC和锁机制的结合,MySQL的可重复读隔离级别既能保证事务内数据的一致性,又能在一定程度上提高并发性能,减少锁的竞争和等待。

Next - Key Lock

Next key lock是行锁和间隙锁的组合。

Next - Key Lock会锁定一个范围,既包括索引记录本身(行锁的功能),又包括索引记录之间的间隙(间隙锁的功能)。例如,对于索引值为10、20、30的记录,Next - Key Lock会锁定(10, 20)、(20, 30)等间隙以及10、20、30这些索引记录本身,这样可以有效防止幻读和数据冲突,在并发场景下更好地保证数据的一致性。

Next - Key Lock的加锁规则

Next - Key Lock的加锁规则较为复杂,以下是一些常见的规则:

等值查询

  • 唯一索引:对于唯一索引的等值查询,若查询记录存在,仅对该记录加行锁;若记录不存在,会在该唯一值的前后间隙加Next - Key Lock。例如,表中有唯一索引列 id ,执行 SELECT * FROM table WHERE id = 5 ,若存在 id 为5的记录,只对该记录加锁;若不存在,则会在小于5和大于5的间隙加锁。

  • 普通索引:在普通索引上进行等值查询时,会对查询到的记录及其所在的间隙加Next - Key Lock。如果查询的记录不存在,会对该索引值两侧的间隙加锁。例如,有普通索引列 age ,执行 SELECT * FROM table WHERE age = 30 ,若有 age 为30的记录,会对这些记录及相邻间隙加锁;若没有,会对小于30和大于30的间隙加锁。

范围查询

  • 全值匹配:当使用唯一索引进行全值匹配的范围查询时,会对范围内的记录加行锁,对范围外的间隙加间隙锁。例如, SELECT * FROM table WHERE id BETWEEN 10 AND 20 ,如果 id 是唯一索引,会对 id 为10到20的记录加行锁,对小于10和大于20的间隙加间隙锁。

  • 非唯一索引或无索引:对于普通索引或无索引列的范围查询,会对范围内的所有记录以及这些记录之间的间隙加Next - Key Lock。例如, SELECT * FROM table WHERE age BETWEEN 30 AND 40 ,如果 age 是普通索引或无索引,会对满足条件的所有记录及它们之间的间隙加锁。

插入操作

  • 插入操作会对插入位置的前一个间隙加Next - Key Lock,以防止其他事务在该位置插入数据,避免出现幻读。例如,在一个有序的索引列中,要插入一个值为5的记录,会对小于5的最大索引值和5之间的间隙加锁。

需要注意的是,这些规则是基于InnoDB存储引擎在可重复读隔离级别下的默认行为,实际应用中可能会因版本、配置等因素有所不同。

相关推荐
Muscleheng43 分钟前
Navicat连接postgresql时出现‘datlastsysoid does not exist‘报错
数据库·postgresql
kyriewen1 小时前
面试官让我查各部门工资最高的员工,我用AI三秒写出窗口函数,他愣了
后端·mysql·面试
小码工作室1 小时前
使用 HAVING 进行 MySQL 集合筛选
mysql
罗超驿1 小时前
18.事务的隔离性和隔离级别:MySQL面试高频考点全解析
数据库·mysql·面试
jran-2 小时前
Redis 命令
数据库·redis·缓存
小江的记录本2 小时前
【Java基础】Java 8-21新特性:JDK21 LTS:虚拟线程、模式匹配switch、结构化并发、序列集合(附《思维导图》+《面试高频考点清单》)
java·数据库·python·mysql·spring·面试·maven
June`2 小时前
多线程redis下如何解决aof重写和rdb持久化的数据一致性问题
数据库·redis·缓存
木心术13 小时前
Windows系统下MySQL与AI工具集成方案:数据存储与调用实践
人工智能·windows·mysql
二宝哥3 小时前
离线安装maven
java·数据库·maven
SZLSDH3 小时前
场景适配论 | 数字孪生IOC建设中渲染技术与智能体能力的协同逻辑
前端·数据库·ai·数字孪生·数据可视化·智能体