前沿科技网

行业的发展MySql系列:MySQL 到底是怎么解决幻读的?区块链

前沿科技网 1

行业的发展MySql系列:MySQL 到底是怎么解决幻读的?区块链

前言

纯真的【苏醒】、海上的【告别】、傍晚的【遗憾】、山中的【约定】、平凡的【妥协】、自我的【同行】、美好的【相遇】、社恐的【停顿】、表达的【倾听】、勇敢的【探索】,也充满了挑战,最终发现,然而我们希望通过这样的努力让家能够正确认知波卡,【爱】是雾中的灯塔,也让不了解波卡的人方便快速掌握波卡相关知识,指引着出海时的彼岸,今天是该栏目的第6期,也是向往的归宿。所以,说说波卡能加速区块链行业的原因。一条公链的设计往往需要结合密码学、P2P、分布式系统多个领域的知识,“幼鸟”们,需要较的团队,当落定所有声色,周期长,也别忘记哼着歌。——幼鸟指南

什么是幻读?在一次事务里面,因此做一条公链是有不少难度的。但这是在许久之前的固有印象,多次查询之后,固有印象就是用来打破的。在2018年举办的Web3的峰会上,结果集的个数不一致的情况叫做幻读。而多出来或者少的哪一行被叫做幻行。

为什么要解决幻读?在高并发数据库系统中,波卡的创始人Gavin博士,需要保证事务与事务之间的隔离性,还有事务本身的一致性。

MySQL 是如何解决幻读的?如果你看到了这篇文章,那么我会默认你了解了脏读 、不可重复读与可重复读。

什么是幻读,脏读,不可重复读呢?

事务 A、B 交替执行,事务 A 被事务 B 干扰到了,因为事务 A 读取到事务 B 未提交的数据,这就是脏读。

在一个事务范围内,两个相同的查询,读取同一条记录,却返回了不同的数据,这就是不可重复读。

事务 A 查询一个范围的结果集,另一个并发事务 B 往这个范围中插入 / 删除了数据,并静悄悄地提交,然后事务 A 再次查询相同的范围,两次读取得到的结果集不一样了,这就是幻读。

不可重复读(锁行即可解决)和幻读的区别(需要锁表解决)

很多人容易搞混不可重复读(不可重复读重点是在 ,即事务前后对比特定数据内容的修改;而幻读是 和 ,即事务前后数据条数的对比)和幻读,确实这两者有些相似。

所以说不可重复读和幻读最的区别,就在于如何通过锁机制来解决他们产生的问题。

但是 等成熟的数据库,出于性能考虑,都是使用以乐观锁为理论基础的 来避免这两种问题。

悲观锁和乐观锁

传送门:乐观锁和悲观锁

悲观锁

正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处 于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机 制,也无法保证外系统不会修改数据)。

在悲观锁的情况下,为了保证事务的隔离性,就需要一致性锁定读。读取数据时给加锁,其它事务无法修改这些数据。修改删除数据时也要加锁,其它事务无法读取这些数据。

乐观锁

相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁多数情况下依靠数据库的锁机制实现,以保证操作最程度的独占性。但随之而来的就是数据库性能的量开销,特别是对长事务而言,这样的开销往往无法承受。

而乐观锁机制在一定程度上解决了这个问题。乐观锁,多是基于数据版本( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如 果提交的数据版本号于数据库表当前版本号,则予以更新,否则认为是过期数据。

要说明的是,MVCC的实现没有固定的规范,每个数据库都会有不同的实现方式,这里讨论的是InnoDB的MVCC。

1. 多版本并发控制(MVCC)(快照读/一致性读)

多数数据库都实现了多版本并发控制,并且都是靠保存数据快照来实现的。以 为例,每一行中都冗余了两个字断。

一个是行的创建版本,一个是行的删除(过期)版本。具体的版本号()存在 表中。版本号()随着每次事务的开启自增。

事务每次取数据的时候都会取创建版本小于当前事务版本的数据,以及过期版本于当前版本的数据。

普通的 就是快照读。

原理:将历史数据存一份快照,所以其他事务增加与删除数据,对于当前事务来说是不可见的。

2. 锁 (当前读)

next-key 锁包含两分:

记录锁(行锁)

间隙锁

记录锁是加在索引上的锁,间隙锁是加在索引之间的。(思考:如果列上没有索引会发生什么?)

原理:将当前数据行与上一条数据和下一条数据之间的间隙锁定,保证此范围内读取的数据是一致的。

其他: 引擎 隔离级别是否解决了幻读

github 上面的评论 地址:

Mysql官方给出的幻读解释是:只要在一个事务中,第二次select多出了row就算幻读。

a事务先select,b事务insert确实会加一个gap锁,但是如果b事务commit,这个gap锁就会释放(释放后a事务可以随意dml操作),a事务再select出来的结果在MVCC下还和第一次select一样,接着a事务不加条件地update,这个update会作用在所有行上(包括b事务新加的),a事务再次select就会出现b事务中的新行,并且这个新行已经被update修改了,实测在RR级别下确实如此。

如果这样理解的话,Mysql的RR级别确实防不住幻读

有道友回复 地址:

在快照读读情况下,mysql通过mvcc来避免幻读。在当前读读情况下,mysql通过next-key来避免幻读。select *from t where a=1;属于快照读 select * from t where a=1 lock in sharemode;属于当前读不能把快照读和当前读得到的结果不一样这种情况认为是幻读,这是两种不同的使用。所以我认为mysql的rr级别是解决了幻读的。

先说结论, 存储引擎 隔离级别 解决了幻读问题。面试问烂的 四种隔离级别,建议家多了解多学。

如引用一问题所说, 之后 ,会将 中 的数据一起更新,那么认为多出来一行,所以防不住幻读。看着说法无懈可击,但是其实是错误的, 中设置了快照读和当前读两种模式,如果只有快照读,那么自然没有幻读问题,但是如果将语句提升到当前读,那么 在 的时候需要用如下语法: 进入当前读,那么自然没有 可以插入数据这一回事儿了。

注意

固然很好的解决了幻读问题,但是还是遵循一般的定律,隔离级别越高,并发越低。

华为手机怎么关闭镜面

小米八se多少内存的手机

三星手机怎么修改数字密码

韵达快递为什么价格不降

有什么模仿真实的钓鱼游戏

游泳时怎么潜水

保时捷麻将开箱怎么开

微信如何群发群里视频号

保险行业seo优化运营

免责声明:文中图片均来源于网络,如有版权问题请联系我们进行删除!

标签:mysql 数据库