• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

浅析MySQL如何实现事务隔离

mysql 搞代码 4年前 (2022-01-09) 18次浏览 已收录 0个评论
文章目录[隐藏]

一、前言

众所周知,MySQL的在RR隔离级别下查询数据,是可以保证数据不受其它事物影响,而在RC隔离级别下只要其它事物commit后,数据都会读到commit之后的数据,那么事物隔离的原理是什么?是通过什么实现的呢?那肯定是通过MVCC机制(Multi-Version Concurrency Control,即多版本并发控制)。

注:MySQL的InnoDB引擎之所以能够支持高性能的并发性能,就是由于MySQL的MVCC机制(归功于undo log、Read-View、),但是本篇不对MVCC过多的介绍。

参考资料:《MySQL实战45讲》系列,虽然讲解的比较清晰,但是仍然需要理解,比如关于视图数组部分我认为是相比较而言没有解释清楚,所以结合资料与自己见解加以记录!

二、RC与RR隔离级别

我们分别开启RC与RR隔离级别实验说明,首先假设有account账户表,在事务ABC开启前,账户中的余额balance为1,即

select balance from account =1; # 结果为1

2.1、RR事务隔离级别下查询结果

当在RR事务隔离级别分别开启三个事务,在不同时间段内做如下操作

  • 事务A(显式开启事务,手动commit提交):查询余额
  • 事务B(显式开启事务,手动commit提交):对id=1的余额加1
  • 事务C(不显式开启事务,自动提交):对id=1的余额加1

我们从时间逻辑上分为三个阶段,分析结果

  • 第一阶段:事务A立马开始事务,随后事务B也紧跟着立马开始事务,然后事务C首先更新balance为2成功,当前balance=2;
  • 第二阶段:事务B更新balance的值,此时先读到当前balance最新值为2,随后set balance=balance+1成功,当前balance=3;
  • 第三阶段:事务A查询balance的值,此时的值为1(这里为什么等于1呢,是怎么实现的呢?不应该是当前最新值3吗?这就是本篇博文讨论的重点),最后commit结束事务,紧接着事务B也commit结束事务

最后事务A读取balance的结果是1,理所当然,RR即为可重复读,即一个事务在执行过程中看到的数据,总是跟这个事务启动时看到的数据是一致的,当前事务不管有没有提交,都不会影响数据,我只需要读取基于快照的数据即可,这就是快照读。但是我们要讨论的是如何在MVCC机制下实现?

注:begin/start transaction 命令并不是一个事本文来源gaodai#ma#com搞@@代~&码*网2务的起点,在执行到它们之后的第一个操作InnoDB表的语句,事务才真正启动。如果你想要马上启动一个事务,可以使用start transaction with consistent snapshot 这个命令。

2.2、RC事务隔离级别下查询结果

同样地,我们在RC隔离下,开启事务ABC,观察事务A最后的balance结果。

最后事务A读取balance的结果是2,理所当然,RC即为读可提交,字面意思就是其他事务只要提交后,当前事务我就能立马读取到最新当前值,这就是当前读。但是我们要讨论的是如何在MVCC机制下实现?

实际上这是因为实现MVCC时用到的一致性读视图,即consistent read view,用于支持RC(Read Committed,读提交)和RR(Repeatable Read,可重复读)隔离级别的实现。

三、事务隔离在MVCC的实现

在探讨MVCC如何实现事务隔离前,我们需要知道是视图数组、一致性视图等概念,才能帮助更好理解MVCC帮助事务实现了隔离。

3.1、数据行ROW的多版本


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:浅析MySQL如何实现事务隔离

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址