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存储引擎在可重复读隔离级别下的默认行为,实际应用中可能会因版本、配置等因素有所不同。

相关推荐
前端 贾公子3 小时前
LangGraph == 图的状态(State)管理 (下)
运维·服务器·数据库
zlwool3 小时前
机械行业ERP与进销存的合规选型边界
数据库·erp
梦想的颜色3 小时前
【AI速览】RAG 向量数据库选型:Milvus、Chroma、Qdrant、PGVector 全维度横向对比
数据库·milvus·chroma·rag·pgvector·向量库·qdrant
小溪学编程4 小时前
向量数据库 Milvus 基础实践:从入门到上手
数据库·milvus
数据最前线4 小时前
雪上加霜,Oracle向蓝色巨人最后的阵地发起挑战
数据库·oracle
于眠牧北4 小时前
Charles配置指定域名抓取和雷电模拟器中抓取APP接口配置
数据库·redis·缓存
stillstream_ink4 小时前
一个缺失的状态校验,让 Mall4j 的订单系统开了 4 个后门
mysql·测试
福娃筱欢4 小时前
57014 canceling statement due to user request(金仓 KingbaseES)
数据库·kingbase·金仓数据库
ClouGence5 小时前
SAP HANA 数据同步遇到长事务,如何兼顾实时性与完整性?
数据库·后端
数据库小学妹5 小时前
数据库管理工具有哪些?2026主流工具分类与选型对照
数据库·数据库管理工具·数据库工具·信创数据库·数据库客户端