菲洛嘉青春动能素135HA FILLMED® NCTF 135HA LED指示灯的常见故障分析 智微智能 Elkhartlake K075终端,零售产业新选择 天空蓝拓客管理系统详细介绍版 muso公链项目 天使计划 是什么?[秘] 独家揭秘最前沿的家装“黑科技”——掌赋 天博体育欧洲杯特辑,东道主法兰西的失意2016 亚马逊的送货侦察员 学习听起来像挡泥板 Google Comics Factory使ML变得容易 笑着说-男性或女性 Amazon Rekognition中更好的人脸检测 关于Spaun的真相-大脑模拟 两个聊天机器人彼此聊天-有趣又怪异 GANPaint:将AI用于艺术 WCF和WF给予社区 从耳朵到脸 所有神经网络的深层缺陷 蠕虫在尾巴上平衡杆子 Kickstarter上的OpenCV AI套件 TensorFlow-Google的开源AI和计算引擎 众包取代新闻工作者 Google的DeepMind学会玩街机游戏 哑机器人V智能机器人 .NET与.NET 5融为一体 Google的深度学习-语音识别 LInQer将.NET LINQ移植到Javascript 机器人TED演讲-新的图灵测试? GAN的发明者加入苹果 您的智能手机会监视您键入的内容 人工智能帮助改善国际象棋 Zalando Flair NLP库已更新 TensorFlow 1.5包含移动版本 AlphaGo输了一场比赛-比分3-1 虚拟机器学习峰会 Microsoft开源AI调试工具 SharePoint走向移动 F#4.0发出文化变革的信号 克里斯蒂拍卖AI艺术品 人工智能如何区分 Facebook在蒙特利尔的新AI实验室 Mozilla想要您的声音 微软使用极深的神经网络赢得ImageNet 建立AI合作伙伴关系 .NET Core 3-Microsoft几乎回到了起点 神经网络-更好的销售商? Google使用AI查找您的住所 虹膜-适用于Android的Siri证明苹果没有优势 TensorFlow 2提供更快的模型训练 深度学习研究人员将为Google工作
您的位置:首页 >程序人生 >

InnoDB可重复读隔离级别是如何实现的

断断续续花了些时间,参考挺多文章,在自己的理解上总结出来以下内容, 以后忘了的时候可以翻出来看看。如果大家之前不太了解这一部分的东西, 可花点耐心把这篇看完,我想会对各位有一些帮助的,若无收获你来砍我。

InnoDB默认隔离级别-可重复读是如何实现的

mysql多事务并发的场景下会出现的问题:1、脏读2、不可重复读3、幻读隔离级别1、读未提交(Read Uncommitted)2、读已提交(Read Committed)3、可重复读(Repeatable Read)4、可串行化(Serializable)常见锁乐观锁和悲观锁共享锁(Shared Lock)也叫读锁或S锁排它锁(Exclusive Lock)也叫写锁或X锁行锁(Record Lock)间隙锁(Gap Lock)Next-Key LockMVCC(multiversion concurrency control)事务版本号MVCC在InnoDB中的实现在RR可重复读隔离级别下的增删查改delete:update:insert:select: 快照读(snapshot read)和当前读(locking read)快照:快照读:当前读:InnoDB如何在可重复读级别解决了幻读的问题可重复读间隙锁

mysql多事务并发的场景下会出现的问题:

1、脏读

事务A执行过程中的一次查询,读到了事务B修改但并未提交的数据, 后来B回滚,导致A读到了错误数据,这是脏读。 在这里插入图片描述

2、不可重复读

事务A两次相同查询的间隔中,事务B修改了这些记录的数据并提交, 导致A两次读到的记录数据不一致,这是不可重复读。 在这里插入图片描述

3、幻读

事务A两次相同查询的间隔中,事务B插入了符合条件的记录并提交, 导致A两次读到的记录条数不一致,这是幻读。 在这里插入图片描述

隔离级别

标准隔离级别总共有四种

1、读未提交(Read Uncommitted)

一般不会用于实际项目。

2、读已提交(Read Committed)

大部分数据库的默认隔离级别,如oracle、sql server等, 但是不包括mysql InnoDB。

3、可重复读(Repeatable Read)

mysql InnoDB默认的隔离级别。

4、可串行化(Serializable)

事务隔离的最高级别,会使数据库的并发性能大幅下降,现实中应用很少。

各隔离级别对应的问题: 在这里插入图片描述

常见锁

在分析今天的问题之前,我们先了解一些常见锁的基础概念。 在这里插入图片描述

乐观锁和悲观锁

它们不是真实存在的锁,只是一种机制或者说是理论。

共享锁(Shared Lock)也叫读锁或S锁

若事务A对数据对象a加上S锁,则事务A只能读a; 其他事务还可以再对a加S锁,却不能加X锁,直到A释放a上的S锁; 这样保证了其他事务可以读a,但在A释放a上的S锁之前不能对a做任何修改。

排它锁(Exclusive Lock)也叫写锁或X锁

若事务A对数据对象a加上X锁,则事务A可以读或写a,其他事务则不可以再对a加任何锁。

行锁(Record Lock)

锁住对应的行,使其它事务无法修改这些数据,但是无法限制insert操作。

间隙锁(Gap Lock)

锁住一个范围,使其它事务无法在该范围内插入数据。(这个我后面会再细说)

Next-Key Lock

Record Lock + Gap Lock。

MVCC(multiversion concurrency control)

多版本并发控制MVCC是以乐观锁为理论基础的一种可以用来增强并发性的强大技术。 在这里插入图片描述

事务版本号

事务版本号是一个从1开始的自增计数,是事务的唯一标识, 事务开启的时候分配,版本号的大小可以用来表示事务的串行化顺序,用于事务可见性的判断。

MVCC在InnoDB中的实现

在InnoDB中,会在每行数据后添加两个额外的隐藏的值, 这两个值一个记录这行数据何时被创建(创建它的事务的版本号), 另外一个记录这行数据何时被删除(删除它的事务的版本号)。

在RR可重复读隔离级别下的增删查改

delete:

记录对应行的删除版本号为当前事务版本号,delete也是假删除。

update:

1、删除原来记录,删除版本号同上; 2、新增一条记录,创建版本号为当前事务版本号。

insert:

同上第2步。

select:

查询创建版本号<=当前事务版本号and(删除版本号>当前事务版本号 or 删除版本号为null)的记录。

快照读(snapshot read)和当前读(locking read)

快照:

事务中第一个这样读读到的数据的一个readView,即该时间点数据的一个快照。

快照读:

在RR隔离级别下,同一事务中后边所有这样的读读到的都是第一个这样读的快照, 或是被当前事务刷新过的快照,这样做到了可重复读。

当前读:

读取当前最新版本的数据。 (当前读的具体定义,大家可以去打听一下,这里只是顺便提一下。)

举个简单的例子: 假设事务A更新表中某一记录的a字段,而事务B也更新这条记录的b字段, 事务B先提交,如果事务A读取的是这条记录快照版本,那么它看不到事务B所提交的修改, 在此基础上更新的话就会覆盖B之前的修改,这样一来,B的修改就丢失了,这是write skew,而这样是不可接受的。

所以,在写的时候一定不是快照读,而是当前读。

InnoDB如何在可重复读级别解决了幻读的问题

可重复读

在这里插入图片描述 这段话的大致意思是,在默认的隔离级别中,普通的SELECT用的是快照读不加锁。 而对于当前读、UPDATE和DELETE,则需要加锁,至于加什么锁视情况而定: 如果对一个唯一索引使用了唯一的检索条件,那么只需锁定索引记录即可; 如果你没有使用唯一索引作为检索条件,或者用到了索引范围扫描, 那么将会使用间隙锁或者next-key锁以此来阻塞其它会话向这个范围内的间隙INSERT数据,避免幻读; 如果你使用没有索引的字段作为检索条件,那么会给全表加上X锁!

间隙锁

下面是InnoDB的聚集索引结构图,其中非叶子节点里蓝色的区域即是索引之间的间隙。 在这里插入图片描述 假设一个索引包含以下几个值:10、11、13、20,那么表的索引间隙: (负无穷, 10), (10, 11), (11, 13), (13, 20), (20, 正无穷)。

至于InnoDB为什么要采用间隙锁这样的方式去避免幻读,毕竟这样会不可避免地锁住一些非必要的区间,由于本人水平有限,不太明白,希望有懂得的人说一下。

参考文章:

狂乱的贵公子:MySQL事务隔离级别的实现原理 ameng:Innodb中的事务隔离级别和锁的关系 风雨之间:MySQL是如何解决不可重复读隔离级别中的幻读问题的 littlewhit:MySql进阶-间隙锁(gap-key) 邓小闲:答MySQL 是如何实现四大隔离级别的?

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。