暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

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

IT技术精选文摘 2021-10-14
948

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

MySQL事务的四大隔离级别

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

01



读未提交

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

02



读已提交

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

03



可重复读

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

04



串行化

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

1

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


1

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


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

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

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

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

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

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

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

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


什么是MVCC?



MVCC实现的关键知识点

01



事务版本号

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

02



隐式字段

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

03



undo log

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

04



版本链

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



05



快照读和当前读

     



06



Read View



MVCC实现原理分析


1

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


  • 获取事务自己的版本号,即事务ID
  • 获取Read View
  • 查询得到的数据,然后Read View中的事务版本号进行比较。
  • 如果不符合Read View的可见性规则, 即就需要Undo log中历史快照;
  • 最后返回符合规则的数据
  • InnoDB 实现MVCC,是通过

  • Read View+ Undo Log
  •  

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



1

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


1

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

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






文章转载自IT技术精选文摘,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论