[MySQL] 事务管理(二) 事务的隔离性底层

news2025/5/24 21:47:10

事务的隔离性底层

  • 1.数据库并发的场景
  • 2.读-写
    • 2.1MVCC三个变量
      • 2.1.1 3个记录隐藏列字段
      • 2.1.2 undo日志
    • 模拟MVCC
    • select 的读取
      • 2.1.3 Read View(读视图)
  • 3.RR与RC的区别

1.数据库并发的场景

  1. 读-读:不存在问题,也不需要并发控制
  2. 读-写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读
  3. 写-写:有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失

2.读-写

一般来说上面的场景中读写的场景占比是最大的。
多版本并发控制(MVCC )是一种用来解决读-写冲突的无锁并发控制。
他会给事务分配一个单向递增的事务ID,为每个修改保存一个版本,版本和事务ID关联,读操作只读取改事务开始前的数据快照,它解决了

  1. 并发读写数据库的时候,可以做到在读操作的时候不用阻塞写操作,写操作的时候不用阻塞读操作
  2. 还解决了脏读,幻读,不可重读的问题,但不能解决更新丢失的问题

2.1MVCC三个变量

2.1.1 3个记录隐藏列字段

在这里插入图片描述

2.1.2 undo日志

我们把它理解为MySQL 中的一段内存缓冲区,用来保存日志数据的就行

模拟MVCC

在这里插入图片描述

假如有一个事务10,他现在要更新数据;

  1. 先给事务10加锁
  2. 我们把原始的数据拷贝一份到undo log 中;
  3. 现在数据库中有两份数据,把张三的名字改成李四后,那么DB_TRX_ID就变成了事务10,回滚指针里面存放的就是undo log中被修改的原始数据的地址。
  4. 事务10提交,释放锁

在这里插入图片描述
现在又多了一个事务11要update李四里面的age改称38

  1. 先给事务11加锁
  2. 把要被修改的数据做一份拷贝,到undo log中,
  3. 现在有两份数据,把age改成38后,DB_TRX_ID变成事务11,回滚指针就变成了undo log中的第一个数据的地址。

这样,我们就有了一个基于链表记录的历史版本链。所谓的回滚,无非就是用历史数据,覆盖当前数据。上面的一个一个版本,我们可以称之为一个一个的快照

select 的读取

当前读:读取最新的记录,就是当前读。增删改,都叫做当前读
快照读:读取历史版本(一般而言),就叫做快照读。

很多事务在CURD的时候都是当前读,是要加锁的,那么这个时候有select要进行读取最新版本的数据的时候也需要加锁,这就是串行化。
当时如果是快照读,是不受加锁限制的, 所以加锁只针对于最新版本

决定select是当前读还是快照读的是隔离级别;
事务都是原子的。所以,无论如何,事务总有先有后。 那么多个事务在执行中,CURD操作是会交织在一起的。那么,为了保证事务的“有先有后”,是不是应该让不同的事务看到它该看到的内容,这就是所谓的隔离性与隔离级别要解决的问题。也就是先来的事务不应该看到后来事务的数据。

2.1.3 Read View(读视图)

**Read View就是事务进行快照读操作的时候生产的读视图(Read View),**在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID,这个ID是递增的,所以最新的事务,ID值越大)。

Read View在MySQL源码中,就是一个类,本质是用来进行可见性判断的。即当我们某个事务执行快照读的时候,对该记录创建一个Read View读视图,把它比作条件,用来判断当前事务能够看到哪个版本的数据,既可能是当前最新的数据,也有可能是该行记录的undo log里面的某个版本的数据。

我们看看它的结构

class ReadView {
    // 省略...
private:
    /* 高水位,大于等于这个ID的事务均不可见*/
    trx_id_t m_low_limit_id;

    /* 低水位,小于这个ID的事务均可见 */
    trx_id_t m_up_limit_id;

    /* 创建该 Read View 的事务ID*/
    trx_id_t m_creator_trx_id;

    /* 创建视图时的活跃事务id列表*/
    ids_t m_ids;

    /* 配合purge,标识该视图不需要小于m_low_limit_no的UNDO LOG,
     * 如果其他视图也不需要,则可以删除小于m_low_limit_no的UNDO LOG*/
    trx_id_t m_low_limit_no;

    /* 标记视图是否被关闭*/
    bool m_closed;

    // 省略...
};

在这里插入图片描述
我们在实际读取数据版本链的时候,可以读取到每一个版本对应的事务ID,即:当前记录的DB_TRX_ID;
我们现在手里面有的东西就有,当前快照读的ReadView 和 版本链中的某一个记录的DB_TRX_ID.
问题:当前快照读,应不应该读取到当前版本的记录
通过版本对应的事务ID与Read View的ID的大小进行判断
在这里插入图片描述

注意:视图是一个对象,初始化之后就不会在改变了。
我们能看到的额数据应该是:

  1. up_limit_id>DB_TRX_ID
  2. 同一个时期活跃的ID,但是不在我的m_ids中(这个事务在我之前已经提交了)

3.RR与RC的区别

  • 正是Read View生成时机的不同,从而造成RC,RR级别下快照读的结果的不同
  • 在RR级别下的某个事务的对某条记录的第一次快照读会创建一个快照及Read View,将当前系统活跃的其他事务记录起来
  • 此后在调用快照读的时候,还是使用的是同一个Read View,所以只要当前事务在其他事务提交更新之前使用过快照读,那么之后的快照读使用的都是同一个Read View,所以对之后的修改不可见;
  • 即RR级别下,快照读生成Read View时,Read View会记录此时所有其他活动事务的快照,这些事务的修改对于当前事务都是不可见的。而早于Read View创建的事务所做的修改均是可见
  • 而在RC级别下的,事务中,每次快照读都会新生成一个快照和Read View,这就是我们在RC级别下的事务中可以看到别的事务提交的更新的原因
  • 总之在RC隔离级别下,是每个快照读都会生成并获取最新的Read View;而在RR隔离级别下,则是同一个事务中的第一个快照读才会创建Read View,之后的快照读获取的都是同一个Read View。
  • 正是RC每次快照读,都会形成Read View,所以,RC才会有不可重复读问题。

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

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

相关文章

20、.NET SDK概述

.NET SDK(Software Development Kit) 是微软提供的一套开发工具包,用于构建、运行和管理基于 .NET 平台的应用程序。它包含了一组丰富的工具、库和运行时环境,支持开发者在多种操作系统(如 Windows、Linux 和 macOS&am…

18-21源码剖析——Mybatis整体架构设计、核心组件调用关系、源码环境搭建

学习视频资料来源:https://www.bilibili.com/video/BV1R14y1W7yS 文章目录 1. 架构设计2. 核心组件及调用关系3. 源码环境搭建3.1 测试类3.2 实体类3.3 核心配置文件3.4 映射配置文件3.5 遇到的问题 1. 架构设计 Mybatis整体架构分为4层: 接口层&#…

冒泡排序、插入排序、快速排序、堆排序、希尔排序、归并排序

目录 冒泡排序插入排序快速排序(未优化版本)快速排序(优化版本)堆排序希尔排序归并排序各排序时间消耗对比 冒泡排序 冒泡排序核心逻辑就是对数组从第一个位置开始进行遍历,如果发现该元素比下一个元素大,则交换位置,如果不大,就…

CD27.【C++ Dev】类和对象 (18)友元和内部类

目录 1.友元 友元函数 几个特点 友元类 格式 代码示例 2.内部类(了解即可) 计算有内部类的类的大小 分析 注意:内部类不能直接定义 内部类是外部类的友元类 3.练习 承接CD21.【C Dev】类和对象(12) 流插入运算符的重载文章 1.友元 友元函数 在CD21.【C Dev】类和…

QT安装详细步骤

下载 清华源 : 清华源 1. 2. 3. 4.

Unity游戏多语言工具包

由于一开始的代码没有考虑多语言场景,导致代码中提示框和UI显示直接用了中文,最近开始提取代码的中文,提取起来太麻烦,所以拓展了之前的多语言包,降低了操作复杂度。最后把工具代码提取出来到单独项目里面,…

实验三 I/O地址译码

一、实验目的 掌握I/O地址译码电路的工作原理。 二、实验电路 实验电路如图1所示,其中74LS74为D触发器,可直接使用实验台上数字电路实验区的D触发器,74LS138为地址译码器, Y0:280H~287H&…

视觉语言导航(VLN):连接语言、视觉与行动的桥梁

文章目录 1. 引言:什么是VLN及其重要性?2. VLN问题定义3. 核心挑战4. 基石:关键数据集与模拟器5. 评估指标6. 主要方法与技术演进6.1 前CLIP时代:奠定基础6.2 后CLIP时代:视觉与语言的统一 7. 最新进展与前沿趋势 (202…

计算机网络中科大 - 第7章 网络安全(详细解析)-以及案例

目录 🛡️ 第8章:网络安全(Network Security)优化整合笔记📌 本章学习目标 一、网络安全概念二、加密技术(Encryption)1. 对称加密(Symmetric Key)2. 公钥加密&#xff0…

XCTF-web(四)

unserialize3 需要反序列化一下:O:4:“xctf”:2:{s:4:“flag”;s:3:“111”;} php_rce 题目提示rce漏洞,测试一下:?s/Index/\think\app/invokefunction&functioncall_user_func_array&vars[0]phpinfo&vars[1][]1 flag&#xff1…

在Vue项目中查询所有版本号为 1.1.9 的依赖包名 的具体方法,支持 npm/yarn/pnpm 等主流工具

以下是 在Vue项目中查询所有版本号为 1.1.9 的依赖包名 的具体方法,支持 npm/yarn/pnpm 等主流工具: 一、使用 npm 1. 直接过滤依赖树 npm ls --depth0 | grep "1.1.9"说明: npm ls --depth0:仅显示直接依赖&#xf…

若依微服务版启动小程序后端

目录标题 本地启动,dev对应 nacos里的 xxx-xxx-dev配置文件 本地启动,dev对应 nacos里的 xxx-xxx-dev配置文件

莒县第六实验小学:举行“阅读世界 丰盈自我”淘书会

4月16日,莒县第六实验小学校园内书香四溢、笑语盈盈,以“阅读世界 丰盈自我”为主题的第二十四届读书节之“淘书会”活动火热开启。全校师生齐聚一堂,以书会友、共享阅读之乐,为春日校园增添了一抹浓厚的文化气息。 活动在悠扬的诵…

国产数据库与Oracle数据库事务差异分析

数据库中的ACID是事务的基本特性,而在Oracle等数据库迁移到国产数据库国产中,可能因为不同数据库事务处理机制的不同,在迁移后的业务逻辑处理上存在差异。本文简要介绍了事务的ACID属性、事务的隔离级别、回滚机制和超时机制,并总…

C++学习记录:

今天我们来学习一门新的语言,也是C语言最著名的一个分支语言:C。 在C的学习中,我们主要学习的三大组成部分:语法、STL、数据结构。 C的介绍 C的历史可追溯至1979年,当时贝尔实验室的本贾尼斯特劳斯特卢普博士在面对复杂…

等离子体浸没离子注入(PIII)

一、PIII 是什么?基本原理和工艺 想象一下,你有一块金属或者硅片(就是做芯片的那种材料),你想给它的表面“升级”,让它变得更硬、更耐磨,或者有其他特殊功能。怎么做呢?PIII 就像是用…

idea中提高编译速度研究

探索过程: 有三种情况: 第一种: idea中用eclipse编译器编译springboot项目,然后debug启动Application报错找不到类。 有待继续研究。 第二种: idea中用javac编译器编译springboot项目,重新构建用时&a…

静态链接part2

编译 语义分析 由语义分析器完成,这个步骤只是完成了对表达式的语法层面的分析,它并不了解这个语句是否真的有意义(例如在C语言中两个指针做乘法运算,这个语句在语法上是合法的,但是没有什么意义;还有同样…

Vue3+Vite+TypeScript+Element Plus开发-17.Tags-组件构建

系列文档目录 Vue3ViteTypeScript安装 Element Plus安装与配置 主页设计与router配置 静态菜单设计 Pinia引入 Header响应式菜单缩展 Mockjs引用与Axios封装 登录设计 登录成功跳转主页 多用户动态加载菜单 Pinia持久化 动态路由 -动态增加路由 动态路由-动态删除…

3D语义地图中的全局路径规划!iPPD:基于3D语义地图的指令引导路径规划视觉语言导航

作者: Zehao Wang, Mingxiao Li, Minye Wu, Marie-Francine Moens, Tinne Tuytelaars 单位:鲁汶大学电气工程系,鲁汶大学计算机科学系 论文标题: Instruction-guided path planning with 3D semantic maps for vision-language …