事务隔离级别的无锁实现方式 -- MVCC

MVCC的全称是Multiversion Concurrency Control(多版本并发控制器),是一种事务隔离级别的无锁的实现方式,用于提高事务的并发性能,即事务隔离级别的一种底层实现方式。

在了解MVCC之前,我们先来回顾一些简单的知识点:数据库的隔离级别和并发场景。

数据库的隔离级别

主要用来解决多个事务在并发的情况下对同一个数据进行读写操作所产生的一些列线程不安全的问题。

  • 脏读 – 读未提交(RU)
    • 事务A读取到了事务B还未提交的数据。
  • 不可重复读 – 读已提交(RC)
    • 事务A读取到事务B已经提交的数据,可以解决脏读问题,但会出现不可重复读。
  • 可重复读(RR)
    • 同一是事务下,事务在执行期间,多次读取同一数据时,能够保证读取到的数据是一致的,可以解决不可重复读问题,但在事务读取过程中,如果有另外一个新事务新增/变更,会出现幻读。
  • 串行化(serializable)
    • 最高的隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读,幻读和不可重复读的问题,但是这种事务隔离级别效率最低,比较耗费数据库性能。

读已提交:

解决脏读问题为什么不使用行锁?如果我们在事务一中对数据进行修改操作时给数据添加一个行锁,那么接下来的事务中想要执行SQL语句进行查询操作,那么该操作将会被阻塞,直到修改操作执行完毕,行锁被解开为止,如此一来,就会降低并发性。

三种并发场景

  • 读 - 读
    • 不存在线程安全问题,不需要关心并发
  • 读 - 写
    • 有线程安全问题,可能会存在数据更新丢失的问题,比如第一类更新丢失,第二类更新丢失

第一类更新丢失:事务A回滚时,将已经提交的事务B更新的数据覆盖了

第二类更新丢失:事务A提交覆盖了事务B已经提交的数据,造成事务B所做的操作丢失

什么是MVCC

定义

即多版本并发控制,是一种并发控制的方法,一般在数据库管理系统中实现对数据库的并发访问,在编程语言中实现事务内存。

目的

在最早的数据库系统中只有读 - 读之间可以并发,读 - 写、写 - 写之间都要阻塞。在引入多版本并发控制技术之后,只有写 - 写之间相互阻塞,其他三种操作都可以并行,这样就达到了提高InnoDB引擎并发度的目的。

实现

在MySQL的内部实现中,InnoDB是通过undo log实现,undo log可以找回数据的历史版本。找回的历史版本可以提供给用户读(按照隔离级别定义,有些读请求只能看到比较老的数据版本),也可以在回滚的时候覆盖数据页上的数据,在InnoDB内部中,会记录一个全局的活跃读写事务数据组,其主要用来判断事务的可见行

MVCC的三个关键点

MVCC是如果无锁地实现事务的隔离级别的呢?主要就是靠以下三个关键因素:

隐藏列

在数据库表单中除了我们创建的原数据的列外,数据库帮我们维护的三个看不到的隐藏列:DB_TRX_ID(事务ID),DB_TRX_ID(存储旧的事务的指针),(ROW_ID)
在这里插入图片描述

undo log

回滚实现:

通过两个隐藏列trx_id(最近一次提交事务的ID)和roll_pointer(上个版本的地址)建立一个版本链。并在事务中读取的时候生成一个Read View(读视图),在Read Committed隔离级别下,每次读取都会生成一个读视图,而在Repeatable Read隔离级别下,只会在第一次读取时生成一个读视图

在这里插入图片描述

ReadView

定义

不加锁的select就是快照读,即不加锁的非阻塞读。(快照读的前提是非serializable隔离级别,在该隔离级别下,快照读会退化为当前读),之所以出现快照读,是基于高并发性能的考虑,快照读的实现是基于MVCC的,可以认为MVCC是行锁的变种,但是他在很多情况下避免了加锁操作,降低了开销。因为多版本的原因,导致快照读可能读取到的不一定是数据的最新版本,而有可能是历史版本

当前读和快照读与MVCC关系

MVCC可以理解为是一个“维护数据的多个版本,使得读写操作没有冲突”的概念,是一种理想状态。而在MySQL中,快照读,就是实现MVCC理想模型的其中一个具体的非阻塞读功能,而相对而言,当前读就是一个悲观锁的具体功能实现

具体实现&&判断顺序

存储三条数据:creator_trx_id(当前事务ID),min_trx_id(当前未提交的事务的ID),max_trx_id(未开始的事务)

  • 首先通过undolog拿到最新版本的数据,最新一次修改本条数据的事务ID
  • 第一次判断:将当前事务ID与最新一次修改本条数据的事务ID进行比较
    • 二者相等–>本条版本的数据是在当前事务中保存的–>该条数据可以读取
    • 二者不相等则不能直接拿到该值,继续进行判断
  • 第二次判断:比较最新一次修改本条数据的事务ID和最小的事务ID
    • 小于–>当前版本数据是在事务开始之前保存的–>该条数据可以读取到
    • 大于等于–>不能直接拿到该值,继续进行判断
  • 第三次判断:比较最新一次修改本条数据的事务ID和最大的事务ID
    • 大于–>当前版本的数据是在本事务开始之后保存的–>本数据不能被读取–>顺着指针找到上一个版本的数据
  • 第四次判断:比较最新一次修改本条数据的事务ID是否在最小事务ID和最大事务ID之间
    • 存在于二者之间–>当前版本的数据是在未提交的并发事务中
      • 如果事务隔离级别是读已提交–>该条数据不能被读取
    • 不存在于二者之间–>沿着指针找到上一个版本的数据,再进行以上四次判断

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

终端工具命令行颜色配置(解决终端工具连上服务器之后,无颜色问题)

本期主题: 讲解使用mobaxterm等终端工具连上服务器,但是命令行没有颜色的问题 目录 1. 问题描述2. 原因解释3.测试 1. 问题描述 使用终端工具(Mobaxterm等)连上服务器之后,发现终端工具没有颜色,如下图&am…

API接口京东开放平台item_get-获得京东商品详情API接口根据商品ID查询商品标题价格描述等详情数据

京东商品详情API接口可以提供以下方面的信息: 商品基础信息:包括商品的标题、价格、描述、图片等基本信息,这是构建电商平台的基础数据。商品分类信息:帮助用户更好地了解商品所属的类别,便于商品筛选和查找。商品销售…

RK3568平台 驱动实现IIC设备读取十六位寄存器状态

一.项目需求 要求读取GVS2715这个IIC设置寄存器的值来获取版本号,GVS2715这个芯片是十六位寄存器。 当使用i2ctool工具读取十六位寄存器的时候,发现无法读取出来,读取的都是XXXX。 二.从零开始写IIC设备驱动读取十六位寄存器的状态 #includ…

CentOS 7安装Zookeeper

说明:本文介绍如何在CentOS 7操作系统下使用Zookeeper 下载安装 首先,去官网下载所需要安装的版本,我这里下载3.4.9版本; 上传到云服务器上,解压 tar -xvf zookeeper-3.4.9.tar.gz修改配置 进入Zookeeper目录下的co…

Spark-机器学习(1)什么是机器学习与MLlib算法库的认识

从这一系列开始,我会带着大家一起了解我们的机器学习,了解我们spark机器学习中的MLIib算法库,知道它大概的模型,熟悉并认识它。同时,本篇文章为个人spark免费专栏的系列文章,有兴趣的可以收藏关注一下&…

前端标记语言HTML

HTML(HyperText Markup Language)是一种用于创建网页的标准标记语言。它是构建和设计网页及应用的基础,通过定义各种元素和属性,HTML使得开发者能够组织和格式化文本、图像、链接等内容。 HTML的基本结构 文档类型声明&#xff0…

SpringBoot+FreeMaker

目录 1.FreeMarker说明2.SpringBootFreeMarker快速搭建Pom文件application.properties文件Controller文件目录结构 3.FreeMarker数据类型3.1.布尔类型3.2.数值类型3.3.字符串类型3.4.日期类型3.5.空值类型3.6.sequence类型3.7.hash类型 4.FreeMarker指令assign自定义变量指令if…

开源版中文和越南语贷款源码贷款平台下载 小额贷款系统 贷款源码运营版

后台 代理 前端均为vue源码,前端有中文和越南语 前端ui黄色大气,逻辑操作简单,注册可对接国际短信,可不对接 用户注册进去填写资料,后台审批,审批状态可自定义修改文字显示 源码免费下载地址抄笔记 (chaob…

详解构造函数

前言 希望这篇文章是有意义的,能够帮助初学者理清构造函数的概念,关系及误区。首先定义一个日期类,借助日期类讲解构造函数。 class Date {public:void Init(int year, int month, int day) //初始化数据的方法{_year year;_month month…

CDP7 下载安装 Flink Percel 包

下载链接:https://www.cloudera.com/downloads/cdf/csa-trial.html 点击后选择版本, 然后点击download now,会有一个协议,勾选即可,然后就有三个文件列表, 我这里是已经注册登录的状态,如果没…

64B/66B GT Transceiver 配置

一、前言 前一篇文章已经讲述了64B/66B的编码原理,此篇文章来配置一下7系列GT的64B/66B编码。并讲述所对应的例子工程的架构,以及部分代码的含义。 二、IP核配置 1、打开7 Series FPGAs Transceiver Wizards,选择将共享逻辑放置在example …

【面试题】s += 1 和 s = s + 1的区别

文章目录 1.问题2.发现过程3.解析 1.问题 以下两个程序真的完全等同吗? short s 0; s 1; short s 0; s s 1; 2.发现过程 初看s 1 和 s s 1好像是等价的,没有什么区别。很长一段时间内我也是这么觉得,因为当时学习c语言的时候教科书…

【数据挖掘】实验6:初级绘图

实验6:初级绘图 一:实验目的与要求 1:了解R语言中各种图形元素的添加方法,并能够灵活应用这些元素。 2:了解R语言中的各种图形函数,掌握常见图形的绘制方法。 二:实验内容 【直方图】 Eg.1&…

【linux深入剖析】深入理解软硬链接 | 动静态库的制作以及使用

🍁你好,我是 RO-BERRY 📗 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 目录 1.理解软硬链接1.1 操作观…

pyqt和opencv结合01:读取图像、显示

在这里插入图片描述 1 、opencv读取图像用于pyqt显示 # image cv2.imread(file_path)image cv2.cvtColor(image, cv2.COLOR_BGR2RGB)# 将图像转换为 Qt 可接受的格式height, width, channel image.shapebytes_per_line 3 * widthq_image QImage(image.data, width, hei…

vue3 uniapp微信登录

根据最新的微信小程序官方的规定,uniapp中的uni.getUserInfo方法不再返回用户头像和昵称、以及手机号 首先,需获取appID,appSecret,如下图 先调用uni.getUserInfo方法获取code,然后调用后台的api,传入code&…

ssm049基于Vue.js的在线购物系统的设计与实现+vue

在线购物系统 摘 要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于在线购物系统当然也不能排除在外,随着网络技术的不断成熟,带动了在线购物系统,它彻底改…

【氮化镓】GaN HEMTs结温和热阻测试方法

文章《Temperature rise detection in GaN high-electron-mobility transistors via gate-drain Schottky junction forward-conduction voltages》,由Xiujuan Huang, Chunsheng Guo, Qian Wen, Shiwei Feng, 和 Yamin Zhang撰写,发表在《Microelectroni…

Linux调试器之gdb

前言 我们前面介绍了几个基本的环境开发工具。例如通过yum我们可以安装和卸载软件、通过vim我们可以写代码、通过gcc和g我们可以编译代码成可执行程序。但是如何在Linux下调试代码呢?我们并未介绍,本期我们将来介绍最后一个工具 --- 调试器gdb。 本期内…

Tomcat服务器入门介及用postman工具简单接收数据 2024详解

Tomcat服务器 简介 Tomcat是一个开源的Servlet容器,也是一个支持Java Servlet和JSP技术的Web服务器。它由Apache软件基金会开发和维护。Tomcat的主要作用是将Java Servlet和JavaServer Pages(JSP)等动态网页技术部署到服务器上,…