当前位置: 首页 > ops >正文

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

http://www.xdnf.cn/news/7992.html

相关文章:

  • leetcode 438. 找到字符串中所有字母异位词
  • Linux `nc` 命令详细讲解
  • vue3:十四、角色权限管理-表格引入-树形表格
  • Axure系统原型设计列表版方案
  • BERT框架:自然语言处理的革命性突破
  • PostgreSQL 14 pacemaker 高可用集群
  • czml数据以及应用
  • uniapp打包报错:重新在manifest.json中生成自己的APPID
  • MacBookPro上macOS安装第三方应用报错解决方案:遇到:“无法打开“XXX”,因为无法确定(验证)开发者身份?怎么解决
  • Android 网络全栈攻略(三)—— 从三方库原理来看 HTTP
  • 代码走读 Go 语言 Map 的实现
  • MAX96752FGTN/V+T:双LVDS(OLDI)输出的GMSL2解串器架构与应用探讨——汽车与工业视频传输方案深度分析
  • 新能源汽车移动充电服务:如何通过智能调度提升充电桩可用率?
  • 从零基础到最佳实践:Vue.js 系列(9/10):《单元测试与端到端测试》
  • Elasticsearch 分页查询的 from+size 有什么缺陷?如何优化深度分页?比较scroll API与search_after的差异
  • 软考中级软件设计师——设计模式篇
  • window 显示驱动开发-指定 GDI 硬件加速渲染操作
  • WebRTC:实时通信的未来之路
  • redis搭建最小的集群,3主3从
  • Android-ViewModel+LiveData学习总结
  • Python爬虫实战:研究Grab 框架相关技术
  • HTTP Digest 认证:原理剖析与服务端实现详解
  • 如何开发一个MCP Server
  • Google机器学习实践指南(梯度下降篇)
  • 关于pgSQL配置后Navicat连接不上的解决方法
  • JAVA开发工具延长方案
  • 大模型在闭合性胫骨平台骨折诊疗全流程中的应用研究报告
  • MySql添加非空字段时的“伪空”问题
  • Elasticsearch搜索排名优化
  • 如何在 Mac M4 芯片电脑上卸载高版本的 Node.js