Mysql-事务(隔离级别,事务底层原理,MVCC)

什么是事务?有哪些特性?

事务:事务指的是逻辑上的一组操作,组成这组操作的各个单元要么全都成功,要么全都失败。
事务特性:

  • 原子性(Atomicity): 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  • 一致性(Consistency):事务前后数据的完整性必须保持一致
  • 隔离性(Isolation):多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。隔离性由隔离级别保障。
  • 持久性(Durability): 一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

事务并发可能产生那些问题?

1 脏读:一个事务读到了另一个事务未提交的数据
2 不可重复读:一个事务读到了另一个事务已经提交(update)的数据。引发事务中的多次查询结果不一致,数据中的值不一致。
3 虚读 /幻读:一个事务读到了另一个事务已经插入(insert)的数据。导致事务中多次查询的结果不一致,比如一个事务向表中插入了一条数据,这个时候另一个事务读取到了这条数据这就是幻读,实际上不应该读到这条数据。
4 丢失更新,举个例子比如事务T1,T2都读取了表中的某一行数据,事务T1对一个表的数据做了更新更为值A,事务T1提交以后,T2也对这个数据进行了修改改为B并提交,这个时候在事务T1里面查询这个数据得到的值是B,T1对数据的修改A被丢失了。
导致这个问题的根本原因就是并发问题,这两个事务可以同时对这个数据进行修改

事务的隔离级别

1 read uncommitted 读未提交【RU】,一个事务读到另一个事务没有提交的数据
存在:3个问题(脏读、不可重复读、幻读)。
2 read committed 读已提交【RC】,一个事务读到另一个事务已经提交的数据
存在:2个问题(不可重复读、幻读)。
解决:1个问题(脏读)
3 repeatable read:可重复读【RR】,在一个事务中读到的数据始终保持一致,无论另一个事务是否提交
解决:3个问题(脏读、不可重复读、幻读)msql默认的隔离级别
4 serializable 串行化,同时只能执行一个事务,相当于事务中的单线程
解决:3个问题(脏读、不可重复读、幻读)

事务的底层原理

前面我们提到了四个问题,我们来解决这些问题。

解决方案一:基于锁并发控制LBCC

1 解决丢失更新的问题
我们在事务T1读取这样行数据的时候就直接加读锁,这个时候T2想要来修改这个数据需要加写锁是不被允许的,就必须等待这个读锁释放,T2才能对对数据进行更新,锁释放的时候事务T1已经执行完成,保证了不会丢失事务T1的更新。
在这里插入图片描述
2 解决读已提交(Read Committed)
读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。这可以通过“瞬间共享读锁”和“排他写锁”实现, 即事务需要对某些数据进行修改必须对这些数据加 X 锁,事务结束后才会释放X锁,读数据时需要加上 S 锁,当数据读取完成后立刻释放 S 锁,不用等到事务结束。

3 解决可重复读取(Repeatable Read)
禁止不可重复读取和脏读取,但是有时可能出现幻读数据。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
Mysql默认使用该隔离级别。这可以通过“共享读锁”和“排他写锁”实现,即事务需要对某些数据进行修改必须对这些数据加 X 锁,读数据时需要加上 S 锁,当数据读取完成并不立刻释放 S 锁,而是等到事务结束后再释放。

解决方案二:基于版本并发控制MVCC

MVCC全称叫多版本并发控制,是RDBMS常用的一种并发控制方法,用来对数据库数据进行并发访问,实现事务。核心思想是读不加锁,读写不冲突。在读多写少的OLTP应用中,读写不冲突非常重要,极大的增加了系统的并发性能,这也是为什么几乎所有的RDBMS,都支持MVCC的原因。MVCC 实现原理关键在于数据快照,不同的事务访问不同版本的数据快照,从而实现事务下对数据的隔离级别。虽然说具有多个版本的数据快照,但这并不意味着必须拷贝数据,保存多份数据文件(这样会浪费存储空间),InnoDB通过事务的Undo日志巧妙地实现了多版本的数据快照。
这里介绍一下UndoLog
InnoDB 引擎对一条记录进行操作(修改、删除、新增)时,要把回滚时需要的信息都记录到 undo log 里,比如:
1)在插入一条记录时,要把这条记录的主键值记下来,这样之后回滚时只需要把这个主键值对应的记录删掉
2)在删除一条记录时,要把这条记录中的内容都记下来,这样之后回滚时再把由这些内容组成的记录插入到表中.
3)在更新一条记录时,要把被更新的列的旧值记下来,这样之后回滚时再把这些列更新为旧值
会产生两种日志:
1 insert Undo 日志:在Insert操作中产生的Undo日志
由于insert操作的记录只对本身可见,对于其它事务此记录是不可见的,所以insert undo log 可以在事务提交后直接删除,不需要等待回收
在这里插入图片描述
2 Update Undo日志:Update或Delete 操作中产生的Undo日志
Update操作会对已经存在的行记录产生影响,为了实现MVCC多版本并发控制机制,因此Update Undo日志不能在事务提交时就删除,而是在事务提交时将日志放入指定区域,等待 Purge 线程进行最后的删除操作。
在这里插入图片描述
这个时候比如我们需要对第二次更新做回滚操作,这个时候只需要顺着RollPointer指针回退一个版本。

有了上面的Undo Log 我们可以结合是ReadView来实现版本控制
ReadView
ReadView是张存储事务id的表,主要包含当前系统中有哪些活跃的读写事务,把它们的事务id放到一个
列表中。结合Undo日志的默认字段【事务trx_id】来控制那个版本的Undo日志可被其他事务看见。

在这里插入图片描述
m_ids:表示在生成ReadView时,当前系统中活跃的读写事务id列表
m_low_limit_id:事务id下限,表示当前系统中活跃的读写事务中最小的事务id,m_ids事务列表中的最小事务id
m_up_limit_id:事务id上限,表示生成ReadView时,系统中应该分配给下一个事务的id值
m_creator_trx_id:表示生成该ReadView的事务的事务id

  • ReadView怎么产生,什么时候生成?
    开启事务之后,在第一次查询(select)时,生成ReadView
    RC 和 RR 隔离级别的差异本质是因为MVCC中ReadView的生成时机不同
    MVCC 怎么保证事务的RC和RR隔离级别可以看这篇文章, 根据下面判断可见性的原理做了一个案例演示。
    MVCC + ReadView案例

  • 如何判断可见性?
    开启事务执行第一次查询时,首先生成ReadView,然后依据Undo日志和ReadView按照判断可见性,
    按照下边步骤判断记录的版本链的某个版本是否可见。

如果被访问版本的 trx_id 属性值,小于ReadView中的事务下限id,表明生成该版本的事务在生
成 ReadView 前已经提交,所以该版本可以被当前事务访问。
如果被访问版本的 trx_id 属性值,等于ReadView中的 m_creator_trx_id ,可以被访问。
如果被访问版本的 trx_id 属性值,大于等于ReadView中的事务上限id,在生成 ReadView 后才产生的数据,所以该版本不可以被当前事务访问。
如果被访问版本的 trx_id 属性值,在事务下限id和事务上限id之间,那就需要判断是不是在
m_ids 列表中。如果在,说明创建 ReadView 时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建 ReadView 时生成该版本的事务已经被提交,该版本可以被访问。

循环判断Undo log中的版本链某一的版本是否对当前事务可见,如果循环到最后一个版本也不可见的
话,那么就意味着该条记录对该事务不可见,查询结果就不包含该记录。

MVCC下的读操作

在MVCC并发控制中,读操作可以分成两类:快照读 (Snapshot Read)与当前读 (Current Read)
快照读:读取的是记录的可见版本 (有可能是历史版本),不用加锁。刚才案例中都是快照读。
当前读:读取的是记录的最新版本,并且当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录

  • 快照读
    简单的select操作,属于快照读,不加锁。
  • 当前读
    特殊的读操作,或者插入/更新/删除操作,属于当前读,需要加锁,需要读取最新的数据。
select * from table where ? lock in share mode; # 加读锁
select * from table where ? for update;# 加写锁
insert into table values ();# 加写锁
update table set ? where ?;# 加写锁
delete from table where ?;# 加写锁

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

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

相关文章

window下如何安装ffmpeg(跨平台多媒体处理工具)

ffmpeg是什么? FFmpeg是一个开源的跨平台多媒体处理工具,可以用于录制、转换和流媒体处理音视频。它包含了几个核心库和工具,可以在命令行下执行各种音视频处理操作,如剪辑、分割、合并、媒体格式转换、编解码、流媒体传输等。FFmpeg支持多…

探索Java中最常用的框架:Spring、Spring MVC、Spring Boot、MyBatis和Netty

目录 前言 Spring框架 Spring MVC框架 Spring Boot框架 MyBatis框架 Netty框架 结语 作者简介: 懒大王敲代码,计算机专业应届生 今天给大家聊聊探索Java中最常用的框架:Spring、Spring MVC、Spring Boot、MyBatis和Netty,希…

解锁Web3:数字未来的大门

随着科技的不断推进,我们正站在数字时代的新门槛上。Web3,作为互联网的下一个演进阶段,正在逐渐揭开数字未来的面纱。本文将深入探讨Web3的本质、对社会的影响以及在数字时代中所扮演的关键角色。 什么是Web3? Web3是互联网发展的…

Mysql 更新数据

MySQL中使用UPDATE语句更新表中的记录,可以更新特定的行或者同时更新所有的行。基本语法结构如下: UPDATE table_name SET column_name1 value1,column_name2 value2,……, column_namen valuen WHERE(condition); column_name1,column_name2,……,…

嵌入式学习 Day13

一. 指针总结 1.指针概念 a.指针 --- 地址 ---内存单元编号 b.指针 --- 数据类型 ---指针类型 不同语境: 定义一个指针 //指针类型的变量 打印某个变量的指针 //指针 --地址 2.指针变量的定义 基类型 * 变量名 a.基类型 …

Python爬虫解析库安装

解析库的安装 抓取网页代码之后,下一步就是从网页中提取信息。提取信息的方式有多种多样,可以使用正则来提取,但是写起来相对比较烦琐。这里还有许多强大的解析库,如 lxml、Beautiful Soup、pyquery 等。此外,还提供了…

【C/C++ 02】希尔排序

希尔排序虽然是直接插入排序的升级版本,和插入排序有着相同的特性,即原始数组有序度越高则算法的时间复杂度越低(预排序机制),但是是不稳定排序算法。 为了降低算法的时间复杂度,所以我们需要在排序之前尽…

美化背景(拼图小游戏)

package Puzzlegame.com.wxj.ui;import javax.swing.*; import javax.swing.border.BevelBorder; import java.util.Random;public class GameJframe extends JFrame { //游戏主界面 //创建一个二维数组//目的:管理数据//加载图片的时候,会根据二维数组中…

BabylonJS 6.0文档 Deep Dive 摄像机(六):遮罩层和多相机纹理

1. 使用遮罩层来处理多个摄影机和多网格物体 LayerMask是分配给每个网格(Mesh)和摄像机(Camera)的一个数。它用于位(bit)级别用来指示灯光和摄影机是否应照射或显示网格物体。默认值为0x0FFFFFFF&#xff…

【java】常见的面试问题

目录 一、异常 1、 throw 和 throws 的区别? 2、 final、finally、finalize 有什么区别? 3、try-catch-finally 中哪个部分可以省略? 4、try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗&#…

SpringMVC 自动配置

SpringMVC 自动配置 一、WebMvcAutoConfiguration(SpringMVC自动配置)二、DisPatcherServletAutoConfiguration.class(中央调度器自动配置)三、WebMvcConfigurationSupport(SpringMVC组件配置类)四、Servle…

CSS 星空按钮

<template><button class="btn" type="button"><strong>星空按钮</strong><div id="container-stars"><div id="stars"></div></div><div id="glow"><div class=…

安全小记-ngnix负载均衡

目录 一.配置ngnix环境二.nginx负载均衡 一.配置ngnix环境 本次实验使用的是centos7,首先默认yum源已经配置好&#xff0c;没有配置好的自行访问阿里云镜像站 https://developer.aliyun.com/mirror/ 接着进行安装工作 1.首先创建Nginx的目录并进入&#xff1a; mkdir /soft &…

IS-IS:03 ISIS链路状态数据库

一个 OSPF 链路状态数据库是若干条 LSA 的集合。与此相似&#xff0c;一个 IS-IS 链路状态数据库是若干条 LSP 的集合。与 OSPF 链路状态数据库不同&#xff0c; IS-IS 链路状态数据库有 level-1 和 level-2 之分。 在IS-IS 协议中&#xff0c;每一条 LSP 都有一个剩余生存时间…

基于UDP的套接字通信(附通信代码)

基于UDP的套接字通信 udp是一个面向无连接的&#xff0c;不安全的&#xff0c;报式传输层协议&#xff0c;udp的通信过程默认也是阻塞的。 不需要建立连接 UDP通信过程中&#xff0c;每次都需要指定数据接收端的IP和端口 UDP不对收到的数据进行排序&#xff0c;在UDP报文的…

Adobe ColdFusion 反序列化漏洞复现(CVE-2023-38203)

0x01 产品简介 Adobe ColdFusion是美国奥多比(Adobe)公司的一套快速应用程序开发平台。该平台包括集成开发环境和脚本语言。 0x02 漏洞概述 Adobe ColdFusion存在代码问题漏洞,该漏洞源于受到不受信任数据反序列化漏洞的影响,攻击者通过漏洞可以代码执行,可导致服务器失…

第17节-高质量简历写作求职通关-投递反馈

&#xff08;点击即可收听&#xff09; 投递跟进和感谢信 如果对一家公司特别心仪&#xff0c;但是投递简历后一直得不到回复怎么办&#xff1f; 面试之后觉得自己没有表现好怎么办&#xff1f; 面试完几天了&#xff0c;依然没有得到回应怎么办&#xff1f; 这个时候你需要写一…

RabbitMQ多种工作场景详解

目录 1、hello world体验 2、Work queues 工作序列 3、Publish/Subscribe订阅与发布 4、Routing 基于内容的路由 5、Topics 基于话题的路由 6、Headers 头部路由机制 7、Publisher Confirms 发送者消息确认 ​ 1、发布单条消息 ​ 2、发送批量消息 ​ 3、异步确认消息…

【JVM】运行时数据区域,内存如何分配和对象在内存中的组成

目录 一.运行时数据区域 1.线程独享 2.线程共享 二.内存如何分配 1.指针碰撞法 2.空闲列表法 3.TLAB 三.对象在内存中的组成 ​编辑1.对象头 2.实例数据 3.对齐填充 一.运行时数据区域 1.线程独享 &#xff08;1&#xff09;栈 虚拟机栈&#xff1a;每个 Java 方法在…

GPT-SoVITS 测试

开箱直用版&#xff08;使用 AutoDL&#xff09; step1 打开地址 https://www.codewithgpu.com/i/RVC-Boss/GPT-SoVITS/GPT-SoVITS-Official 选择 AutoDL创建实例&#xff0c;选择 3080ti 机器 step2 创建好实例之后&#xff0c;进入命令行&#xff0c;输入命令 echo {}>…