深入理解MySQL底层事务隔离级别的实现原理

75250bc114454d40361ed369a0b059df.png

若有收获,请记得点在看和分享

b20b6e15c6cc49bd84bcdc7605cf3e78.png

147134a4bfdc57d01cd5b8e554944efe.png

MySQL事务的四大隔离级别

d3925bf77a88551994f4e4e2d1152154.gif

30ff5b362096850c8576dd6e58e55065.png

为了解决并发事务存在的脏读、不可重复读、幻读等问题,数据库大叔设计了四种隔离级别。分别是读未提交,读已提交,可重复读,串行化(Serializable)。

01

读未提交

      读未提交隔离级别,只限制了两个数据不能同时修改,但是修改数据的时候,即使事务未提交,都是可以被别的事务读取到的,这级别的事务隔离有脏读、重复读、幻读的问题。       

02

读已提交

      读已提交隔离级别,当前事务只能读取到其他事务提交的数据,所以这种事务的隔离级别解决了脏读问题,但还是会存在重复读、幻读问题。       

03

可重复读

      可重复读隔离级别,限制了读取数据的时候,不可以进行修改,所以解决了重复读的问题,但是读取范围数据的时候,是可以插入数据,所以还会存在幻读问题。       

04

串行化

      事务最高的隔离级别,在该级别下,所有事务都是进行串行化顺序执行的。可以避免脏读、不可重复读与幻读所有并发问题。但是这种事务隔离级别下,事务执行很耗性能。     

1

四大隔离级别,都会存在哪些并发问题呢?

741cee11c9928d4a5f9d89abe047fa72.png

1

数据库是如何保证事务的隔离性的呢?

数据库是通过加锁,来实现事务的隔离性的。

这就好像,如果你想一个人静静,不被别人打扰,你就可以在房门上加上一把锁。

加锁确实好使,可以保证隔离性。

比如串行化隔离级别就是加锁实现的

但是频繁的加锁,导致读数据时,没办法修改,修改数据时,没办法读取,大大降低了数据库性能

那么,如何解决加锁后的性能问题的?

答案就是,MVCC多版本并发控制

它实现读取数据不用加锁,可以让读取数据同时修改。修改数据时同时可读取。

8809dcb7a9a9b16075511b75faf86e20.png

什么是MVCC?

9e0cadee4a2b36d0417d750ca523382b.gif

0563e00669940f461c23a43399f7ad0a.png

34d09d67359274e1b76048724cafa2a3.png

MVCC实现的关键知识点

1c2475f8a25648ea065deb598d709843.gif

01

事务版本号

      事务每次开启前,都会从数据库获得一个自增长的事务ID,可以从事务ID判断事务的执行先后顺序。这就是事务版本号。       

02

隐式字段

      对于InnoDB存储引擎,每一行记录都有两个隐藏列trx_id、roll_pointer,如果表中没有主键和非NULL唯一键时,则还会有第三个隐藏的主键列row_id。

6da05a92a59161b1c9dd9b00186a1d46.png

03

undo log

      undo log,回滚日志,用于记录数据被修改前的信息。在表记录修改之前,会先把数据拷贝到undo log里,如果事务回滚,即可以通过undo log来还原数据。

babe588272eb75ae855a8fa1a1c409af.png

04

版本链

      多个事务并行操作某一行数据时,不同事务对该行数据的修改会产生多个版本,然后通过回滚指针(roll_pointer),连成一个链表,这个链表就称为版本链。如下:      

7bae3e7287eb73ce89ace09fcba64bcb.png

1846c95e6a8eec98cfcd812e01099b46.png

05

快照读和当前读

fa50cb590916657f0d9f2be41de4df23.png

06

Read View

38ffbeb8c6421e5d1b0108ad6f721ab6.png

6717612cc6d81bc08c07b308d08396d3.png

34dd1c293c70ef6074d5ae757647646d.png

MVCC实现原理分析

9691dda732e7ddd704a76df50d153321.gif

1

查询一条记录,基于MVCC,是怎样的流程

  • 获取事务自己的版本号,即事务ID

  • 获取Read View

  • 查询得到的数据,然后Read View中的事务版本号进行比较。

  • 如果不符合Read View的可见性规则, 即就需要Undo log中历史快照;

  • 最后返回符合规则的数据

  • InnoDB 实现MVCC,是通过

Read View+ Undo Log

实现的,Undo Log 保存了历史快照,Read View可见性规则帮助判断当前版本的数据是否可见。

1

读已提交(RC)隔离级别,存在不可重复读问题的分析历程

f11928e13224d998fa222a9b93640215.png

1f53a07f5801b8266fb71f77cfc1f1ac.png

0035e03c2dc66edaf5d138fd450bcc90.png

55943565caa4a49487dc0878c08d96ca.png

9e42885543a7051ef6669c9549ec566d.png

db176a3a577b1a9bced45ed124653b36.png

1

可重复读(RR)隔离级别,解决不可重复读问题的分析

81294d02a7ea4afef2184f96fe81ce4f.png

ad50cde30572eb848a85c9ccdef2ba61.png

4f27b9a697976013b79932f65593b36e.png

3d30132718824704230e4e0b826f704b.png

589eb6444121cbf40931b983b6000f41.png

e190d8e99c08df4563a812d3044c6602.png

c3d35003d24a5f867907f27bd7503fae.png

c59a9290327ed959fd7dbd0aed0eb940.png

a531d0ee784c44c377962813788f1a74.png

其实,上图事务A中,多加了update account set balance=200 where id=5;这步操作,同一个事务,相同的sql,查出的结果集不同了,这个结果,就符合了幻读的定义~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值