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.mzph.cn/news/655852.shtml

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

相关文章

设计模式——2_0 职责链(Chain of Responsibility)

楼下一个男人并得要死,那家隔壁的一家唱着留声机,对面是弄孩子。楼上有两人狂笑;还有打牌声,河中的船上有女人哭她死去的母亲。人类的悲欢并不相通,我只觉得他们吵闹 ——鲁迅 文章目录 定义图纸一个例子:如…

谷歌人工智能视频生成器-LUMIERE(未开源)

Google重磅发布视频生成模型Lumiere 据说后续会开源 亮点1.支持文本到视频与图像到视频 亮点2.画风迁移 亮点3.运动蒙版 亮点4.视频编辑 亮点5.视频修复 谷歌视频模型可以生成80帧的片段!不仅画质好、质量高,而且时长更长。 视频局部编辑 这项功能可以…

强化学习原理python篇06(拓展)——DQN拓展

强化学习原理python篇06(拓展)——DQN拓展 n-steps代码结果 Double-DQN代码结果 Dueling-DQN代码结果 Ref 拓展篇参考赵世钰老师的教材和Maxim Lapan 深度学习强化学习实践(第二版),请各位结合阅读,本合集只…

【学习笔记】vue3的watch

尚硅谷Vue2.0Vue3.0全套教程丨vuejs从入门到精通 课程 P152节 笔记: 情况一:监视ref所定义的一个响应式数据 情况二:监视ref所定义的多个响应式数据 这两种情况比较简单,正常写就ok: 情况三:监视reactive所…

关机恶搞小程序

1. system("shutdown")的介绍 当system函数的参数是"shutdown"时,它将会执行系统的关机命令。 具体来说,system("shutdown")的功能是向操作系统发送一个关机信号,请求关闭计算机。这将触发操作系统执行一系列…

MacOS安装反编译工具JD-GUI以及解决无法打开的问题

目录 一.下载地址 二.安装 三.问题 四.解决办法 1.显示包内容 2.找到Contents/MacOS/universalJavaApplicationStub.sh 3.修改sh文件 4.保存后再次打开即可 一.下载地址 Java Decompiler 二.安装 将下载下来的 jd-gui-osx-1.6.6.tar 解压,然后将 JD-GUI.a…

Hadoop3.x基础(1)

来源:B站尚硅谷 这里写目录标题 大数据概论大数据概念大数据特点(4V)大数据应用场景 Hadoop概述Hadoop是什么Hadoop发展历史(了解)Hadoop三大发行版本(了解)Hadoop优势(4高)Hadoop组成&#xf…

IntelliJ创建一个springboot工程

安装jdk mac教程 windows教程 安装maven mac教程 windows教程 建议: 在本地磁盘新建一个文件夹叫maven,然后把下载的maven安装到这里。在后续的IntelliJ操作中,配置maven的settings.xml和repository地址为这个目录下的地址。 创建sprin…

【架构】Docker实现集群主从缩容【案例4/4】

实现集群主从缩容【4/4】 接上一节,在当前机器为4主4从的架构上,减缩容量为3主3从架构。即实现删除6387和6388. 示意图如下: 第一步:查看集群情况(第一次) redis-cli --cluster check 127.0.0.1:6387roo…

c# Get方式调用WebAPI,WebService等接口

/// <summary> /// 利用WebRequest/WebResponse进行WebService调用的类 /// </summary> public class WebServiceHelper {//<webServices>// <protocols>// <add name"HttpGet"/>// <add name"HttpPost"/>// …

【Linux】fork()函数

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

Docker 安装篇(CentOS)

Docker社区版 Docker从1.13版本之后采用时间线的方式作为版本号&#xff0c;分为社区版CE和企业版EE。 社区版是免费提供给个人开发者和小型团体使用的&#xff0c;企业版会提供额外的收费服务&#xff0c;比如经过官方测试认证过的基础设施、容器、插件等。 1、Docker 要求 C…

深度强化学习(王树森)笔记08

深度强化学习&#xff08;DRL&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。本文在ChatGPT辅助下完成。 参考链接 Deep Reinforcement Learning官方链接&#xff1a;https://github.com/wangshusen/DRL 源代码链接&#xff1a;https://github.c…

校园圈子论坛系统--APP小程序H5,前后端源码交付,支持二开!uniAPP+PHP书写!

随着移动互联网的快速发展&#xff0c;校园社交成为了大学生们日常生活中重要的一部分。为了方便校园内学生的交流和互动&#xff0c;校园社交小程序逐渐走入人们的视野。本文将探讨校园社交小程序的开发以及其带来的益处。 校园社交小程序的开发涉及许多技术和设计方面。首先&…

安装elasticsearch、kibana、IK分词器

1.部署单点es 1.1.创建网络 因为我们还需要部署kibana容器&#xff0c;因此需要让es和kibana容器互联。这里先创建一个网络&#xff1a; docker network create es-net 1.2.加载镜像 这里我们采用elasticsearch的7.12.1版本的镜像&#xff0c;这个镜像体积非常大&#xff0…

提升工作效率,畅享便捷PDF编辑体验——Adobe Acrobat Pro DC 2023

作为全球领先的PDF编辑软件&#xff0c;Adobe Acrobat Pro DC 2023将为您带来前所未有的PDF编辑体验。无论您是个人用户还是企业用户&#xff0c;Adobe Acrobat Pro DC 2023将成为您提高工作效率、简化工作流程的得力助手。 一、全面编辑功能 Adobe Acrobat Pro DC 2023提供了…

代码随想录 Leetcode110.平衡二叉树

题目&#xff1a; 代码(首刷看解析 2024年1月30日&#xff09;&#xff1a; class Solution { public:int depth(TreeNode* root) {if (root nullptr) return 0;int leftHeight depth(root->left);if (leftHeight -1) return -1;int rightHeight depth(root->right)…

打造高效经营:开发连锁餐饮管理系统的技术深度解析

为了适应市场的快速发展和提高经营效率&#xff0c;许多连锁餐饮企业纷纷投入开发连锁餐饮管理系统。 一、数字化转型的动力 传统的餐饮经营面临着诸多挑战&#xff0c;如订单管理、库存控制、人力资源等问题。在这样的背景下&#xff0c;连锁餐饮企业迫切需要一种全面而高效…

Flask 入门2

1. 在上一节中&#xff0c;我们使用到了静态路由&#xff0c;即一个路由规则对应一个 URL。而在实际应用中&#xff0c;更多使用的则是动态路由&#xff0c;它的 URL是可变的。 2. 定义一个很常见的路由地址 app.route(/user/<username>) def user(username):return U…

SQL Server ISO镜像文件安装

参考&#xff1a;Sql Server ISO镜像文件安装指南_sqlserveriso文件怎么安装-CSDN博客 参考文件中的步骤基本相同&#xff0c;注意两点 1、尽量安装在D盘&#xff0c;有些组件默认必须安装在C盘&#xff0c;有些会报没有目录的情况 需要在D盘创建目录。 2、我没有windows本地…