浅谈 MySQL 事务隔离方案之 MVCC

本文仅个人学习记录,如有错误,望请指正

我们都知道 MySQLInnoDB 引擎提供了事务特性,并支持四种隔离级别:

  • 读未提交:可以获取其它事务未提交的数据(脏读)
  • 读已提交:可以获取其它事务已经提交(不可重复读)
  • 可重复读:同一事务内读到的数据始终一致
  • 串行化

那么 MySQL 是如何实现事务的隔离的呢?是怎样保证数据在多个事务之间安全的访问呢?
让我们一起探究事务隔离解决方案之 MVCC 👇

1. 什么是MVCC

Multi-Version Concurrency Control,多版本并发控制。顾名思义 MVCC 是一种并发控制的方法,实现对数据的并发访问。

2. 原理

生成一个数据请求时间点的一致性数据快照,并用这个快照来提供一定级别的一致性读取。

3. 落地实现

在数据库每一行记录(数据)中额外保存两个隐藏的列(创建版本、删除版本),这个版本与事务相关联,从而达到各个事务之间数据独立。


定义总是抽象且晦涩的,下面我们通过实际操作来观察一下👇
图文结合,更好理解

  1. 准备一个表 mvcctest,包含两个字段 idname
CREATE TABLE `mvcctest` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

image


  1. 事务1:新增两条记录,并提交事务

image

查询一下是否提交成功

image


  1. 事务2:开启事务,并查询数据(不提交事务)

image


  1. 事务3:插入一条新纪录,并提交事务(在其它事务里观察是否能查询到事务3新增的记录)

image

在表中查看是否新增成功

image


  1. 事务2:回到事务2窗口(此时事务2并未提交),执行第二次查询

image

神奇的现象发生了,当在 事务2 中再次查询时,没有查询到 事务3 刚刚新增的记录
步骤 2 ~ 5 的流程图如下:

image


  1. 事务4:删除第二条记录(jack事务1 新增的,事务2 中已经查询到了 jack,如果在 事务4 里删除了 jack事务2 里还能查询到 jack 吗?),并提交事务(观察对其它事务的影响)

image

在表中查看是否删除成功

image


  1. 事务2:回到事务2窗口(此时事务2并未提交),执行第二次查询

image

神奇的现象发生了,事务4 中已经删除成功的记录,在 事务2 里还能再次查询到(可重复读
步骤 6 ~ 7 的流程图如下:

image


  1. 事务5:修改第一条记录 tomgod事务2 中查询到的第一条记录为 tom,如果在 事务5 里修改了,事务2 里查询到的到底是 tom 还是 jack 呢?),并提交事务(观察对其它事务的影响)

image

在表中查看是否修改成功

image


  1. 事务2:回到事务2窗口(此时事务2并未提交),执行第二次查询

image

神奇的现象发生了,明明已经在 事务5 中修改成功的记录,在 事务2 里还能查询到 事务2 开始时查询到的数据(可重复读
步骤 8 ~ 9 的流程图如下:

image


posted @ 2021-08-10 14:14  超级鲨鱼辣椒  阅读(53)  评论(0编辑  收藏  举报