RR级别为什么不能完全解决幻读案例分析 | 什么是MCVV

      • 0. 知识前要:
      • 1. 举个栗子:
        • 1.1. 栗子一:两次快照读之间存在更新语句,更新其他事务已经更新过的数据
          • 1.1.1. 执行过程分析:
          • 1.1.2. MVCC分析:
        • 1.2. 栗子二:两次快照读之间存在更新语句,更新其他事务insert的数据
        • 1.3. 栗子三:两次快照读之间存在更新语句,要更新的数据不冲突
        • 1.4. 栗子四:使用锁定读取
      • 3. 小结:

0. 知识前要:

  • 要分析这个问题,首先得清楚什么是MVCC,详细的可以查看看一遍就理解:MVCC原理详解
  • 这里小结一下:
    • MVCC 是多版本并发控制,主要实现读写冲突不阻塞,这个读指的是快照读
    • 它的实现主要依赖三个隐式字段、undo 日志、Read View
    • 每行记录除了自定义的字段外,还有隐式主键、事务 id、指向 undo 日志的指针
    • undo 日志记录有原始数据和修改数据,是个记录链,链首是最新的修改
    • Read View 是一致性读视图,用来判断记录的某个版本是否对当前事务可见
      • m_ids:当前系统中那些活跃(未提交)的读写事务ID列表
      • min_limit_id:最小的事务id
      • max_limit_id:最大的事务id,即分配给下一个事务的id值
      • creator_trx_id:当前的事务id
      • 匹配规则如下:
        在这里插入图片描述
    • RR 级别都是复用同一个 Read View,RC 则是每次快照读生成一个

1. 举个栗子:

  • 初始数据:
  • 在这里插入图片描述
1.1. 栗子一:两次快照读之间存在更新语句,更新其他事务已经更新过的数据
  • 事务B的更新语句提交之后,事务A对事务B已提交的数据再进行更新,则事务B已提交的数据对事务A是可见的
  • 官方文档也是这么介绍的,innodb-consistent-read,但文档也没找到原因
    ·在这里插入图片描述

在这里插入图片描述

  • 本栗子事务A最后的查询语句结果mobile=‘BBB’,amount=2000
1.1.1. 执行过程分析:
  • 存储引擎执行update语句的过程
    • 先从缓存池Buffer Pool读取数据,没有数据则从磁盘文件加载到缓存池
    • 更新时再缓存池修改,并将更新的数据记录到redo日志缓存池
    • 事务提交时,redo日志缓冲池根据策略写入redo日志磁盘文件,还会将本次修改的数据写入binlog,最后给redo日志追加commit标记
      ·在这里插入图片描述
  • 事务A执行update语句时,事务B已经提交,意味着更新时会先获取最新的数据(不管是缓缓存池还是数据库加载的)
1.1.2. MVCC分析:

在这里插入图片描述

  • 事务A第一次查询生成的视图快照,按照Read View的可见性判断规则,对比Undo版本链的记录
    • 对比版本链最新的数据
      • min_limit_id =<trx_id(100)< max_limit_id
      • m_ids包含版本记录的trx_id(100),且trx_id(100) = creator_trx_id
      • 所以第二次查询语句查询到的就是mobile=‘BBB’,amount=2000的数据
1.2. 栗子二:两次快照读之间存在更新语句,更新其他事务insert的数据

在这里插入图片描述

  • 事务A更新的数据是事务B新插入的数据,存在数据冲突
  • 和上述栗子一一样,此时事务B新插入的数据对事务A是可见的
  • 更新的时候会去取最新的数据取更新
  • 所以最终查询结果会看到id = 2,4 的数据,并且id=4 的amout = 2000;
1.3. 栗子三:两次快照读之间存在更新语句,要更新的数据不冲突

在这里插入图片描述

  • 和上面栗子一类似,只不过事务A更新的是id=5的数据
    • 事务B更新提交id=1的数据,事务A再更新id=5的数据,更新的数据与事务B提交的不冲突
    • 所以事务B提交的数据对事务A是不可见的
    • 最后的查询结果还是mobie = ‘AAA’,amount = 1000
1.4. 栗子四:使用锁定读取

在这里插入图片描述

  • 事务A第二条查询语句结果:mobie = ‘BBB’,amount = 1000
  • 事务A第二条查询语句使用FOR UPDATE 、FOR SHARE( LOCK IN SHARE MODE) 这类锁定读取(也属于当前读)
  • 从结果层面来看,猜测这类锁定读取不会使用版本链记录取匹配,而是直接获取的最新数据

3. 小结:

  • RR 级别通过 MVCC 保证快照读不会出现幻读,通过临建锁保证当前读不会出现幻读;
  • 但不能保证先快照读,再当前读的情况,所以严格意义上不算完全解决幻读
    • 如果两次查询之间出现Update、Delete语句这类当前读,并且操作的语句数据与别的事务提交的数据冲突,则DML对当前事务可见
    • 如果是锁定读取,会直接读取最新数据

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LightDB24.1 存储过程支持inner和outer对变量的引用

背景 Oracle oracle plsql支持如下场景&#xff1a; 在for循环中&#xff0c;将select查询的结果给一个record类型&#xff0c;这一操作也被称为隐式游标操作。record类型中一个字段用来接收查询结果中的一个select查询语句&#xff08;update,delete,insert在这个语法中都会…

CentOS安装zsh与ohmyzsh

文章目录 安装 zsh安装 ohmyzsh安装插件.zshrc 配置终端效果 安装 zsh yum install -y git curl # 安装zsh yum install -y zsh # 查看已经安装shell cat /etc/shells # 切换shell chsh -s /bin/zsh安装 ohmyzsh 国内镜像 sh -c "$(curl -fsSL https://gitee.com/pocmo…

算法·动态规划Dynamic Programming

很多人听到动态规划或者什么dp数组了&#xff0c;或者是做到一道关于动态规划的题目时&#xff0c;就会有一种他很难且不好解决的恐惧心理&#xff0c;但是如果我们从基础的题目开始深入挖掘动规思想&#xff0c;在后边遇到动态规划的难题时就迎难而解了。  其实不然&#xff…

数据结构与算法3-选择排序

文章目录 1. 认识选择排序2. 图示2.1 图示12.2 图示2 3. 代码 1. 认识选择排序 双层for循环&#xff0c;每次选出最小的数放到i位置&#xff0c;时间复杂度O( n 2 n^2 n2)&#xff0c;空间复杂度O(1);从未排序的序列中找到最小&#xff08;或最大&#xff09;的元素&#xff0…

【CNN轻量化】ParameterNet: Parameters Are All You Need 参数就是你所需要的

论文链接&#xff1a;http://arxiv.org/abs/2306.14525 代码链接&#xff1a;https://github.com/huawei-noah/Efficient-AI-Backbones 一、摘要 现有的低FLOPs模型&#xff08;轻量化模型&#xff09;无法从大规模预训练中受益。本文旨在增加大规模视觉预训练模型中的参数数量…

程序员的最佳副业居然是炒股

前言 之前的文章 《程序员的最佳副业居然是这个》讲述了个人的副业选择&#xff0c;和各种做过的副业。最后选择了炒股。那么究竟是否能够在股市里赚到利润呢&#xff1f;以我个人最近的交易记录来看&#xff0c;答案是肯定的。 一个半月赚取了 2898 程序员投资的优势 程序…

netty基础_12.用 Netty 自己实现简单的RPC

用 Netty 自己实现简单的RPC RPC 基本介绍我们的RPC 调用流程图己实现 Dubbo RPC&#xff08;基于 Netty&#xff09;需求说明设计说明代码封装的RPCNettyServerNettyServerHandlerNettyClientHandlerNettyClient 接口服务端(provider)HelloServiceImplServerBootstrap 客户端(…

概率基础——逻辑回归多分类法

概率基础——逻辑回归多分类法 逻辑回归是一种经典的分类算法&#xff0c;通常用于解决二分类问题。然而&#xff0c;在实际应用中&#xff0c;我们经常会遇到多分类任务。本文将简单介绍逻辑回归的理论、多分类方法以及优缺点&#xff0c;并提供一个Python实现的示例。 逻辑…

【MySQL】图形化界面工具DataGrip安装&配置&使用

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C Linux的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的…

npm出现内部错误,重新设置镜像

问题&#xff1a; 报错解释&#xff1a; 这个错误表明你尝试从一个指定的npm镜像源的响应时失败了。可能的原因包括网络问题、镜像源不可用、DNS解析问题或者镜像源的确已经下线或更改。 1.重新设置镜像源 设置淘宝镜像源&#xff1a; npm config set registry https://re…

网络面试——http 和 https 的区别

区别&#xff1a; 1. HTTP 是超文本传输协议&#xff0c;信息是明文传输&#xff0c;HTTPS 是具有安全性的 SSL 加密传输协议。HTTPS 是由 SSL HTTP 协议构建的可进行加密传输、身份认证的网络协议&#xff0c;比 HTTP 协议安全 2. 端口号&#xff1a;http 使用 80 端口&#…

ros小问题之差速轮式机器人轮子不显示(rviz gazebo)

在rviz及gazebo练习差速轮式机器人时&#xff0c;很奇怪&#xff0c;只有个机器人的底板及底部的两个万向轮&#xff0c;如下图&#xff0c; 后来查看相关.xacro文件&#xff0c;里面是引用包含了轮子的xacro文件&#xff0c;只需传入不同的参数即可调用生成不同位置的轮子&…

代码学习第24天----回溯算法

随想录日记part24 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.10 主要内容&#xff1a;回溯算法在代码学习中尤其重要&#xff0c;所以今天继续加深对其的理解&#xff1a;1&#xff1a;递增子序列 &#xff1b;2.全排列 &#xff1b;3.全排列II 491.递…

MySQL基础-----事务(下)

目录 前言 一、并发事务问题 1.赃读 2.不可重复读 3.幻读 二、事务隔离级别 1.相关操作 2.案例演示 前言 本期我们继续上一期事务的内容&#xff0c;本期的主要讲解的是并发事务的相关问题以及解决方式&#xff0c;内容可能会比较难去理解&#xff0c;不过我会尽量详细说…

C++ UML类图

参考文章&#xff1a; &#xff08;1&#xff09;C UML类图详解 &#xff08;2&#xff09;C基础——用C实例理解UML类图 &#xff08;3&#xff09;C设计模式——UML类图 &#xff08;4&#xff09;[UML] 类图介绍 —— 程序员&#xff08;灵魂画手&#xff09;必备画图技能之…

31.HarmonyOS App(JAVA)鸿蒙系统app Service服务的用法

鸿蒙系统app Service服务的用法 后台任务调度和管控 HarmonyOS将应用的资源使用生命周期划分为前台、后台和挂起三个阶段。前台运行不受资源调度的约束&#xff0c;后台会根据应用业务的具体任务情况进行资源使用管理&#xff0c;在挂起状态时&#xff0c;会对应用的资源使用进…

《C语言深度剖析》---------关键字(1)

1.双击实质--->加载内存 windows系统里面&#xff0c;双击的本质就是运行程序&#xff0c;把程序加载到内存里面&#xff1b; 任何程序运行的时候都必须加载到内存里面&#xff1b; 程序没有运行之前在硬盘里面&#xff0c;为什么程序运行之前必须加载到内存里面呢&#…

Spring Web MVC入门(5)

响应 在我们前面的代码例子中, 都已经设置了响应数据Http响应结果可以是数据, 也可以是静态页面, 也可以针对响应设置状态码, Header信息等. 返回静态页面 创建前端页面index.html(注意路径) html代码如下: <!DOCTYPE html> <html lang"en"> <hea…

Nutanix 国产化替代|一文了解 SmartX 超融合替代可行性与迁移方案

2022 年 8 月 19 日&#xff0c;Nutanix&#xff08;路坦力&#xff09;宣布中国市场自 2023 财年起将转型为合作伙伴销售主导模式&#xff0c;引起了广泛关注&#xff1b;同时结合当前 IT 基础架构的国产化趋势背景&#xff0c;不少正在使用和考虑使用 Nutanix 产品的企业开始…

Vue 中预加载组件

在 Vue 中&#xff0c;利用 VueRouter 可以轻松的实现两个组件&#xff08;页面&#xff09;之间的切换&#xff0c;有个常用的设计就是需要在登录页登录后跳转至一个内容页&#xff0c;通常的做法是在登录校验完成之后立即切换路由至内容页&#xff0c;接着内容页发送网络请求…