苏州制作手机网站,吉林省建设项目信息网,厦门网站seo外包,借贷网站开发是否合法来源 | 阿丸笔记提到MySQL的事务#xff0c;我相信对MySQL有了解的同学都能聊上几句#xff0c;无论是面试求职#xff0c;还是日常开发#xff0c;MySQL的事务都跟我们息息相关。而事务的ACID#xff08;即原子性Atomicity、一致性Consistency、隔离性Isolation、持久性D… 来源 | 阿丸笔记提到MySQL的事务我相信对MySQL有了解的同学都能聊上几句无论是面试求职还是日常开发MySQL的事务都跟我们息息相关。而事务的ACID即原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability可以说涵盖了事务的全部知识点所以我们不仅要知道ACID是什么还要了解ACID背后的实现只有这样无论在日常开发还是面试求职都能无往而不利。为了大家更好的阅读体验对ACID的深入分析将分为上下两篇。本篇为上篇主要围绕ACID中的I,也就是“隔离性”展开从基本概念到隔离性的实现最后以一个实战案例进行融会贯通。嗯看完全部内容你都能理那跟面试官侃半小时隔离性就没问题了。事务隔离性的基本概念1.1 什么是ACID中的Isolation,隔离性Isolation,隔离性也有人称之为并发控制concurrency control。事务的隔离性要求每个事务读写的对象对其他事务都是相互隔离的也就是这个事务提交前这个事务的修改内容对其他事务都是不可见的。事务的隔离性主要是解决不同事物之间的相互读写影响。所谓的读写影响注意分为三种脏读读到了别的事务尚未提交commit的变更别人没提交我读到了。不可重复读别的事务提交了变更被当前事务读到了。然后导致本事务多次select的结果不一样读到了别的事务提交的内容。幻读也是读到了别的事务提交的内容但是跟上面的不同之处在于读到了原本不存在的记录。注意不可重复读主要是读到了别的事务update的内容。而幻读是读到了别的事务insert的内容。1.2 隔离性的隔离级别为了解决事务隔离性的问题数据库一般会有不同的隔离级别来解决相应的读写影响。读未提交一个事务B还没提交它的修改就被别的事务A读到了。读已提交一个事务B提交后它的修改被其他事务A看到了。可重复读一个事物B提交前和提交后事务A都无法读到事务B的变更。串行化对同一行记录当出现不同事物的读写冲突时是通过串行化的方式解决的后一个事务必须等前一个事务完成才能执行。不同隔离级别能够解决不同的隔离性问题。需要注意的是这是标准事务隔离级别的定义。在MySQL的innodb引擎中在可重复读级别下通过mvcc解决了幻读的问题具体实现我们后面再讲。同时需要注意的是到目前为止我们说的读都是”快照读”普通的select。后面我们还会提到“当前读”是不一样的哦。事务隔离性的实现要实现事务的隔离性需要了解两个方面的内容一个是锁一个是多版本并发控制MVCC。2.1 事务的行锁InnoDB中实现了两种标准的行级锁共享锁S Lock也叫读锁允许事务读取一行数据。排它锁X Lock也叫写锁允许事务删除或者更新一行数据注意这里没有提到插入哦插入涉及到幻读可以看文章最后的说明普通select语句不会有任何锁那么如何获得共享锁和排它锁呢Select … lock in share mode语句能够获得共享锁Select … for update特殊的select用mysql简单实现分布式锁经常用它、Update、delete语句能够获得排它锁当一个事务A已经获得了行r的共享锁那么另一个事务B可以立刻获得行r的共享锁因为不会改变r的数值这种叫做锁兼容。如果这时候有事务C希望获得行r的排它锁那么就必须等待事务A和事务B释放行r的共享锁之后才能获得排它锁这种叫做锁不兼容。普通的select不会对行上锁而select…lock in share mode会上共享锁select…for update会上排它锁。对于普通的select的读取方式称为”快照读“也叫”一致性非锁定读“。对于带锁的select读取或者update tb set a a1读取a的当前值称为“当前读”也叫“一致性锁定读”。如果在update、insert的时候不能进行select那么服务的并发访问性能就太差了。因此我们日常的查询都是“快照读”不会上锁只有在update\insert\“当前读”的时候才会上锁。而为了解决“快照读”的并发访问问题就引入了MVCC。2.2 多版本并发控制MVCC如果说上面的行锁是一种悲观锁那么MVCC就是一种乐观锁的实现方式而且是一种很常用的乐观锁实现方式。所谓多版本就是一行记录在数据库中存储了多个版本每个版本以事务ID作为版本号。InnoDB 里面每个事务有一个唯一的事务 ID是在事务开始的时候向InnoDB的事务系统申请的并且按照申请顺序严格递增的。假如一行记录被多个事务更新那么就会产生多个版本的记录。以某一行数据作为例子经过两次事务的操作value从22变成了19同时保留了三个事务id15、25、30。在每个记录多版本的基础上需要利用“一致性视图”来做版本的可见性判断。这里我们要区分MySQL里面的两个”视图”概念一个是view通过语法create view … 实现主要创建一个虚拟表用来执行查询语句。一个是InnoDB用来实现mvcc的一致性视图consistent read view纯逻辑概念没有物理结构定义了在事务期间你能看到哪些版本的数据。我们全文提到的“视图”都是第二种主要是支持InnoDB在“读已提交”和“可重复读”级别的并发访问问题。“读未提及”级别下没有一致性视图“读已提交”级别下会在 每个SQL开始执行的时候 创建一致性视图“可重复读”级别下会在 每个事务开始的时候 创建一致性视图“串行化”级别下直接通过加锁避免并发问题下面我们简单介绍一下创建一致性视图的逻辑。以“可重复读”级别为例。当一个事务开启的时候会向系统申请一个新事务id此时可能还有多个正在进行的其他事务没有提交因此在瞬时时刻是有多个活跃的未提交事务id将这些未提交的事务id组成一个数组数组里面最小的事务id记录为低水位当前系统创建过的事务id的最大值1记录为高水位这个数组array 和 高水位就组成了“一致性视图”。有了一致性视图后我们就可以判断一行数据的多版本可见性了无论是“读已提交”还是“可重复读”级别可见性判断规则是一样的区别在于创建快照一致性视图的时间。在当前事务中读取其他某一行的记录对其中的版本号的可见性判断有五种情况建议自己跟着捋一捋挺重要的如果版本号小于“低水位”说明事务已经提交那肯定 可见如果版本号大于“高水位”说明这行数据的这个事务id版本是在快照后产生的那肯定 不可见如果版本号在事务数组array中说明这个事务还没提交所以 不可见如果版本号不在事务数组array中且低于高水位说明这个事务已经提交所以 可见当然无论什么时候自己的事务id中的任何变化都是可见的可以看看下面这个例子更容易理解。系统创建过的事务id1,2,3,4,5,6,7,8,9,10,11,12,13,14,15事务A启动拍个快照此时未提交的事务id有789一致性视图数组array[7,8,9] 高水位16151对于任意一行数据的可见性判断小于7的可见大于16的说明是快照后产生的不可见10-15不在数组array中说明已经提交了可见789在array中说明未提交不可见两个重要结论InnoDB 利用了“所有数据都有多个版本”的这个特性实现了“秒级创建快照”的能力。MVCC的实现就是根据当前事务的事务id为依据创建“一致性视图”利用一致性视图来判断数据版本的可见性。隔离性实战下面我们来两个实战案例将上面的基础概念与实现融会贯通吧。1并发selectupdate 案例id1 的value初始为1。我们看下在不同隔离级别Time5、Time7、Time9事务A查询到的value 分布为多少。“读未提交”222“读以提交”122“可重复读”112串行化112注意这里在事务A提交前事务B都会阻塞直到事务A提交后才能执行2并发update案例id1 的value初始为1在可重复读级别我们看一下你猜猜事务A和事务B读取的value是多少答案是1 和 3可能会产生困惑事务A在启动后快照所以读到了1是正常的但是事务2在启动的时候快照了然后在自己的事务中1怎么会读到3而不是2呢原因很简单即使是在可重复读的级别事务 更新数据 的时候只能用当前读想想也能理解不然update就出现数据不一致了。如果当前的记录的行锁被其他事务占用的话就需要进入锁等待。而读提交的逻辑和可重复读的逻辑类似它们最主要的区别是在可重复读隔离级别下只需要在事务开始的时候创建一致性视图之后事务里的其他查询都共用这个一致性视图在读提交隔离级别下每一个语句执行前都会重新算出一个新的视图。这里我们需要注意的是事务的启动时机。begin/start transaction 命令并不是一个事务的起点在执行到它们之后的第一个操作 InnoDB 表的语句事务才真正启动,一致性视图是在执行第一个快照读语句时创建的。如果你想要马上启动一个事务可以使用 start transaction with consistent snapshot 这个命令一致性视图是在执行 start transaction with consistent snapshot 时创建的。关于幻读前文已经提到了对于普通数据库需要到可串行化的隔离级别才能解决幻读问题。而对于InnoDB存储引擎来说在可重复读级别下就能解决幻读问题。InnoDB存储引擎有三种行锁算法行锁当个行记录上的锁间隙锁Gap Lock锁定一个范围但不包含记录本身Next-Key Lock:就是行锁间隙锁同时锁上一个范围并且锁定记录本身InnoDB就是通过Next-Key Lock解决了幻读的问题。好了关于ACID的隔离性就说到这里你有什么看法欢迎在评论区和我们讨论。「AI大师课」是CSDN发起的“百万人学AI”倡议下的重要组成部分4月份AI大师课以线上技术峰会的形式推出来自微软、硅谷TigerGraph、北邮等产学界大咖就图计算机器学习语音技术、新基建AI、AI医疗等主题展开分享扫描下方二维码免费报名限时再送299元「2020AI开发者万人大会」门票一张。推荐阅读一文教你如何使用 MongoDB 和 HATEOAS 创建 REST Web 服务
一个数据科学家需要哪些核心工具包?
AI 开发者不容错过的 20 个机器学习和数据科学网站
马云为什么救援世界
1分钟售出5万张票电影节抢票技术揭秘
BTC重现“自由落体”式暴跌原来是受这几个因素影响
真香朕在看了