可重复读实现原理

news2025/2/21 20:19:42

浅解释

概念
1、InnoDB 在每行记录后面保存两个隐藏的列,分别保存了数据行的创建版本号和删除版本号。每开始一个新的事务,系统版本号都会递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的创建版本号对比。
2、insert:为插入的每一行保存当前系统版本号作为创建版本号。
3、delete:为删除的每一行保存当前系统版本号作为删除版本号。
4、update:插入一条新数据,保存当前系统版本号作为创建版本号。同时保存当前系统版本号作为原来的数据行删除版本号。
演示

事务A插入一条数据,假设当前系统版本号为1
insert into user (id,name) values (1,'Tom');
得到这条数据
id      nanme       create_version        delete_version
 1       Tom                1      

事务A查询数据---根据事务A版本号
select * from user where id = 1;
得到这条数据
id      nanme       create_version        delete_version
 1       Tom                1      

事务B修改数据,事务B版本号为2
update user set name = 'Jerry' where id = 1;
提交后
id      nanme       create_version        delete_version
 1       Tom                1                    2    
 1       Jerry              2                     
 
事务A查询数据---根据事务A版本号
select * from user where id = 1;
id      nanme       create_version        delete_version
 1       Tom                1                    2
**得出结论:可重复读并不会发生不可重复读**

事务C删除数据
delete from user where id = 1;
id      nanme       create_version        delete_version
 1       Jerry              2                    3

**得出结论:只有新增和修改会修改数据行的创建版本号、删除和修改会修改数据行的删除版本号**        

深解释

必知一
实际上,InnoDB 会在每行记录后面增加三个隐藏字段:
DB_ROW_ID:行ID,随着插入新行而单调递增,如果有主键,则不会包含该列。
DB_TRX_ID:记录插入或更新该行的事务的事务ID。
DB_ROLL_PTR:回滚指针,指向 undo log 记录。每次对某条记录进行改动时,该列会存一个指针,可以通过这个指针找到该记录修改前的信息 。当某条记录被多次修改时,该行记录会存在多个版本,通过DB_ROLL_PTR 链接形成一个类似版本链的概念。
必知二
每开启一个事务时,系统会给该事务会分配一个事务 Id,事务 A 开启事务的时候会生成一个 事务快照ReadView,主要包含以下几个属性
1、m_ids,当前有哪些事务正在执行,且还没有提交,这些事务的 id 就会存在这里;
2、min_trx_id,是指 m_ids 里最小的值
3、max_trx_id,是指下一个要生成的事务 id。下一个要生成的事务 id 肯定比现在所有事务的 id 都大;
4、creator_trx_id,每开启一个事务都会生成一个 ReadView,而 creator_trx_id 就是这个开启的事务的 id。
必知三
有了这个ReadView,这样在访问某条记录时,只需要按照下边的步骤判断记录的某个版本是否可见:
1)如果被访问版本的trx_id与ReadView中的creator_trx_id值相同,意味着当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问。
2)如果被访问版本的trx_id小于ReadView中的up_limit_id值,表明生成该版本的事务在当前事务生成ReadView前已经提交,所以该版本可以被当前事务访问。
3)如果被访问版本的trx_id大于ReadView中的low_limit_id值,表明生成该版本的事务在当前事务生成ReadView后才开启,所以该版本不可以被当前事务访问。
4)如果被访问版本的trx_id属性值在ReadView的up_limit_id和low_limit_id之间,那就需要判断一下trx_id属性值是不是在trx_ids列表中。如果在,说明创建ReadView时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建ReadView时生成该版本的事务已经被提交,该版本可以被访问。

实现1:自己理解的
不好意思,这个图片转正不过来
在这里插入图片描述

实现2:他人博客讲的
1、事务是可以并发执行的,现在有事务 A、事务 B 这两个事务,且这两个都没有提交。事务 A 将会执行多次读操作,来模拟可重复读中多次读取同一行数据的场景。事务 B 则会修改这一行数据
在这里插入图片描述

2、事务 A 开启事务的时候会生成一个 ReadView,所以说这个 ReadView 的创建者就是事务 A,事务 A 的事务 id 是 10,所以 creator_trx_id 就是 10。

此时,总共就只有事务 A、事务 B 这两个事务,而且它们都还没有提交,所以说 m_ids 会把这两个事务 id,10、18 都记录下来。min_trx_id 是 m_ids 里面的最小值,10、18 中最小的显然是 10。当前最大的事务 id 是 18,那么下一个事务的 id 就是 19,max_trx_id 就是 19。

ReadView 生成之后,事务 A 就要去 undo log 版本链中读取值了。

现在只有一条 undo log 日志,但这并不意味着事务 A 就能读到这条日志的值 X。它要先判断这行日志的 trx_id 是否小于当前事务的 min_trx_id。看图我们可以很轻松地发现,日志的 trx_id = 8 小于 ReadView 中 min_trx_id = 10。

这就意味着,这个事务 A 开始执行之前,修改这行数据的事务已经提交了,所以事务 A 是可以查到值 X 的。
3、我们继续看,事务 A 第一次读完之后,事务 B 要修改这行数据了。undo log 会为所有写操作生成日志,所以就会生成一条 undo log 日志,并且它的 roll_pointer 会指向上一条 undo log 日志
在这里插入图片描述

4、紧接着,事务 A 第二次去读这行数据了,情况如下图所示:
在这里插入图片描述

第一次读的时候,开启事务 A 的时候就生成了一个 ReadView,R

此时事务 A 第二次去查询的时候,先查到的是 trx_id = 18 的那条数据,它会发现 18 比最小的事务编号 10 大。那就说明事务编号为 18 的事务,有可能它是读不到的。

​接着就要去 m_ids 里确认是否有 18 这条数据了。发现有 18,那就说明在事务 A 开启事务的时候,这个事务是没有提交的,它修改的数据就不应该被读到。

事务 A 就会顺着 roll_pointer 指针继续往下找,找到了 trx_id = 8 这条日志,发现这条能读,读到的值任然是 x,与第一次读到的结果一致。

成功实现可重复读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/71704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RKMEDIA--VP使用

本章描述rkmedia vp模块 即视频一入四处功能的介绍。 使用场景:主要用在DVR/DMS产品上,需要多路视频节点的输入和获取。 可以rv1126/rv1109可以外接模拟高清RX芯片(NVP6188,TP2815等),达到8路camera输入的能力。 在…

PLSQL导出、导入数据 和 同步数据 以及 navicat 里同步数据 以及解决plsql导出数据乱码问题

PLSQL导出、导入数据 和 同步数据 以及 navicat 里同步数据 以及解决plsql导出数据乱码问题1. 导出数据1.1 导出.pde文件1.2 导出sql文件1.2.1 导出sql压缩文件1.2.1 导出问题——乱码 与 解决乱码问题1. 尝试解决方式12. 尝试解决方式23. 直接换PLSQ版本(最终解决问…

Traysoft AddTapi.NET 支持多条线路

Traysoft AddTapi.NET 支持多条线路 使用Traysoft AddTapi。您可以轻松地将手机功能添加到C#、VB.NET和C应用程序中。添加Tapi。NET将为您提供开发移动应用程序所需的一切。包括:电话呼叫、接收者ID、语音邮件、警告系统、电话呼叫跟踪和监控。添加Tapi。NET继续联系…

微服务框架 SpringCloud微服务架构 25 黑马旅游案例 25.3 我附近的酒店

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构25 黑马旅游案例25.3 我附近的酒店25.3.1 直接开干25 黑马旅游案例 25.3 …

计算机组成大题分析(四)

假设计算机 M 的主存地址为 24 位,按字节编址,采用分页存储管理方式,虚拟地址为 30 位,页大小为 4KB,TLB 采用 2 路组相联方式 和LRU 替换策略,一共8组。请回答一下问题。 (1) 虚拟地址中有哪几位表示虚页号? 哪几位表示内存地址? (2)己知访问 TLB 时虚页号高位部分用作 TLB…

留学Assignment写作语法错误怎么改正?

如何避免Assignment写作中的一些语法错误,在留学生提交论文要求进行润色修改时,经常会碰到一些语法上的错误,这都是英语水平的问题,同时也与自身的习惯相关,下面小编说一下Assignment写作的语法错误的几种情况&#xf…

浙江省AAA级“守合同重信用”公示企业

浙江省“守合同重信用”企业公示,是市场监管部门依企业自愿申请,对符合公示条件企业前两个年度内的合同履约信息向社会公示的行政指导行为。 浙江省“守合同重信用”企业公示实行逐级推荐、分级公示、动态管理制度。企业住所地县级市场监管局受理企业公示…

你还在使用swagger?试试这个吧

文章目录easyyapi插件使用1. 安装插件2. 配置插件3. 编写javadoc4. 上传接口javadoc5. 登录YApi,查看项目接口easyyapi插件使用 1. 安装插件 打开idea的Settings–>Plugins,查找easyyapi插件安装。 2. 配置插件 安装成功后,再次打开Settings–>OtherSett…

公司小程序小程序毕业设计,企业小程序系统设计与实现,微信小程序毕业设计论文怎么写毕设源码开题报告需求分析怎么做

项目背景和意义 目的:本课题主要目标是设计并能够实现一个基于微信小程序公司企业站系统,前台用户使用小程序,后台管理使用基PHP开发,存储使用Mysql数据库;通过后台添加公司信息、资讯、产品等,用户通过小程…

vue+element+electron仿微信实现

一.仿得太像了有木有~ 1.登录窗口 2.主窗口 二.构思,以微信设计布局构思 以微信布局构思,参考element提供的组件;element提供的tabs标签页刚好能实现切换效果,element tabs 标签页;element tabs标签页虽然能达到切换…

如果把网络原理倒过来看,从无到有,一切如此清晰

从物理层到数据链路层 也从上篇我们创造一个计算机网络,你会去怎么设计?,追溯到计算机网络互联的本质就是通信问题,所以从物理层解决使用何种信号来传输比特的问题。 再从物理设备中的集线器,聊到二层的交换机&#…

零基础CSS入门教程(9)——背景颜色和背景图片

本章目录1.任务目标2.背景颜色3.背景图片4.小结1.任务目标 我们前几小节学习了如何设置字体格式&#xff0c;我们这一小节学习一下如何设置背景颜色和图片 2.背景颜色 我们可以通过background-color给标签设置背景颜色&#xff0c;例如&#xff1a; <!DOCTYPE html> …

【世界杯限定】致敬梅西,用Python刻画足球场上的战神

最近卡塔尔世界杯正在火热的进行着&#xff0c;相信球迷们一定不会错过每一场精彩的比赛吧&#xff0c;在看球的同时&#xff0c;小伙伴们不要忘记自己的学习与工作哦&#xff0c;本人纯属路人&#xff0c;虽然不是很懂球&#xff0c;但是很喜欢梅西&#xff0c;所以我开始关注…

云边协同下的统一应用管理: 基于 OpenYurt 和 KubeVela 的解决方案

作者&#xff1a;乔中沛&#xff08;伊灵&#xff09; 背景 随着万物互联场景的逐渐普及&#xff0c;边缘设备的算力也不断增强&#xff0c;如何借助云计算的优势满足复杂多样化的边缘应用场景&#xff0c;让云原生技术延伸到端和边缘成为了新的技术挑战&#xff0c;“云边协…

RNA-seq 详细教程:样本质控(6)

学习目标 了解计数数据变换方法的重要性了解 PCA (principal component analysis)了解如何使用 PCA 和层次聚类评估样本质量1. 质控 DESeq2 工作流程的下一步是 QC&#xff0c;其中包括样本和基因程度上&#xff0c;以对计数数据执行 QC 检查&#xff0c;以帮助我们确保样本或重…

[附源码]Python计算机毕业设计Django右脑开发教育课程管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;我…

iOS现有APP上架流程​

一. 登录App Store Connect​ 1.登录App Store Connect(apple.com)账号密码登录​ 2.点击“我的App”-->”选中升级的APP”-->创建新的APP版本号​ 输入版本的升级内容--》然后点击右上角的“存储”按钮&#xff0c;保存本次修改。​ 上传更新App Store安装包​ Xcode-…

【Rust日报】2022-12-07 测量 Rust 中 HashMap 的开销

测量 Rust 中 HashMap 的开销在处理将大量数据放入 HashMap的项目时&#xff0c;作者开始注意到 HashMap 占用了大量内存并对最小内存使用量进行了粗略计算&#xff0c;得到的常驻内存是预期的两倍多。我们都知道 HashMaps 以空间换取时间。通过使用更多空间&#xff0c;我们能…

Apache HTTP 两个路径穿越漏洞复现

目录 Apache HTTP Server 2.4.49 路径穿越漏洞&#xff08;CVE-2021-41773&#xff09; 漏洞环境&#xff1a; 漏洞复现&#xff1a; 漏洞复现成功&#xff01; Apache HTTP Server 2.4.50 路径穿越漏洞&#xff08;CVE-2021-42013&#xff09; 漏洞复现分析&#xff1a; 漏…

React - Hooks 使用(函数组件中使用 React 特性)

React - Hooks 使用&#xff08;函数组件中使用 React 特性&#xff09;一. 为什么要使用 HOOKS&#xff1f;二. HOOKS 概念三. HOOKS 用法1. useState1.1 参数及返回值1.2 setState 两种写法1.3 setState 示例2. useEffect2.1 useEffect 实例3. useRef3.1 useRef 实例四. 一个…