MySQL 45 讲学习笔记 ☞ 08 事务到底是隔离的还是不隔离的? @ FnEsc | 2021-07-17T13:58:49+08:00 | 3 分钟阅读

begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个操作 InnoDB 表的语句,事务才真正启动。如果你想要马上启动一个事务,可以使用 start transaction with consistent snapshot 这个命令。

序言:

  • MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重复读)。可重复读的核心就是一致性读(consistent read)。

可以通过 SELECT @@tx_isolation; 来查看。

  • begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个操作 InnoDB 表的语句,事务才真正启动。

  • start transaction with consistent snapshot; 的意思是从这个语句开始,创建一个持续整个事务的一致性读快照。

  • 在读提交隔离级别下,start transaction with consistent snapshot; 等效于普通的 start transaction

MySQL “视图”的概念

  • 一个是 view。它是一个用查询语句定义的虚拟表,在调用的时候执行查询语句并生成结果。创建视图的语法是 create view … ,而它的查询方法与表一样。

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

MVCC 里的“快照”

在可重复读隔离级别下,事务在启动的时候就“拍了个快照”。

举例说明:

执行流程事务顺序

结果是:事务 B 查到的 k 的值是 3,而事务 A 查到的 k 的值是 1。

快照的实现方式使用 transaction id & row trx_id 来共同实施,参考如下行状态:

执行流程行状态

所以,数据表中的一行记录,其实可能有多个版本 (row),每个版本有自己的 row trx_id。

高低水位

undo log(回滚日志)如上图的虚线所示,并且旧版本数据值在物理上不存在,而在每次需要的时候计算得来的。(高低水位的计算) 答:InnoDB 利用了“所有数据都有多个版本”的这个特性,实现了“秒级创建快照”的能力。

视图数组

这里,事务 A 的视图数组如下图:

执行流程行状态

参考视图数组里面的,事务 transaction id ,可以得知,事务 A 查询结果确实为 1。

更新逻辑

更新数据都是先读后写的,而这个读,只能读当前的值(即使是在不可见的高水位也需要是最新值),称为“当前读”(current read)。

所以这个读和查询可能不同,当前读为高水位也可,查询只能查询当前可见值。 当前读,总是读取已经提交完成的最新版本(注意排他锁哦!!)。

当前读

而如果上面事务 A 加锁去读的话,也可以读到最高水位的值,查询结果为 3 。

mysql> select k from t where id=1 lock in share mode; -- 读锁(S 锁,共享锁)
mysql> select k from t where id=1 for update; -- 写锁(X 锁,排他锁)

升级版事务流程

假如事务 C 变成了事务 C'

执行流程升级版事务顺序

这样的话可以考虑之前提及到的“两阶段锁协议”了。事务 C’没提交,也就是说 (1,2) 这个版本上的写锁还没释放。而事务 B 是当前读,必须要读最新版本,而且必须加锁,因此就被锁住了,必须等到事务 C’释放这个锁,才能继续它的当前读。

到这里,我们把一致性读、当前读和行锁就串起来了。

© 2021 FnEsc Hugo Site

Powered by Hugo with theme Dream.

avatar

FnEsc 的博客一边担心未来,一边浪费现在。

关于我

FnEsc 的 💜 博客

自从 2021.07 开始搭建该 hugo 博客,作为记录一些生活/技术上的小笔记

2020届应届生,毕业与佛山科学技术学院计算机科学与技术专业

目前职业是 全栈开发程序🐶 打杂工具人

作为传统行业外企电商的 965,使我并没有很勤奋卷

不想那么相关工作为 SAP Fiori 应用开发和维护。

目前主要的技术栈是:

  • Python Web 端架构
  • Django / Odoo 开发

接下来可能想学习的方向是:

  • Python 进阶(流畅的 python)
  • MySQL 知识巩固(MySQL 实战 45 讲)
  • Go 开始学习(Go 语言核心 36 讲)
  • 其他架构/算法尝试学习
社交链接