MySQL事务(二)事务隔离的实现原理:一致性读
今天我们来学习一下MySQL的事务隔离是如何实现的。如果你对事务以及事务隔离级别还不太了解的话,这里左转。
好的,下面正式进入主题。事务隔离级别有4种:读未提交、读提交、可重复读和串行化。首先我们来说一下读未提交和串行化。
- 读未提交:性能最好,因为不加锁,所以可以理解为没有隔离。
- 串行化:读加共享锁,其他事务可并发读,但不能写;写加排他锁,其他事务不能并发写也不能并发读。
这两种方式要么啥都不管,并发性能最好,但也最多问题;要么管得很严,无法并发处理,实现简单。
另外两种,读提交和可重复读,的实现方式就有考究了。
可重复读
首先我们来看一下可重复读是如何实现的。
在可重复读隔离级别下,事务在启动的时候就“拍了个快照”,并且这个快照是基于整个库的。而“快照”在计算机里是拷贝了一份当前的副本文件,但在数据库并发访问场景下,不可能真的拷贝一份数据副本。
实际上,这个快照是基于InnoDB在实现MVCC时用到的一致性读视图来实现的。
MVCC的全称是“多版本并发控制”。这项技术使得InnoDB的事务隔离级别下执行一致性读操作有了保证,换言之,就是为了查询一些正在被另一个事务更新的行,并且可以看到它们被更新之前的值。这是一个可以用来增强并发性的强大的技术,因为这样的一来的话查询就不用等待另一个事务释放锁。这项技术在数据库领域并不是普遍使用的。一些其它的数据库产品,以及MySQL其它的存储引擎并不支持它。
如何实现“快照”
InnoDB里面每个事务有一个唯一的事务ID,叫作transaction id。它是在事务开始的时候向InnoDB的事务系统申请的,是按申请顺序严格递增的。
数据表中的一行记录,其实可能有多个版本(row),每个版本都有自己的row trx_id。如图1所示:

图1 行状态变更图
图中虚线框里是同一行数据的4个版本,当前最新版本是V4,k的值是22,它是被transaction id为25的事务更新的,因此它的row trx_id是25。
其实除了最新版本V4外,其他三个版本实际上是不存在的,它们是由undo log和最新版本数据计算得到的。其中undo段就是图中的虚线箭头的U1、U2、U3,例如V1版本就是根据V4依次执行U3、U2、U1计算得到的。
undo log是回滚日志,保存的是逻辑格式的日志,可用于事务回滚,也可以用于MVCC。
按照可重复读的定义,一个事务启动的时候,能够看到所有已经提交的事务结果。但之后在这个事务执行期间,其他事务的更新对它不可见。
InnoDB为每个事务构成一个数组,用来保存这个事务启动瞬间,当前正在“活跃”的所有事务ID。“活跃”指启动了但还没有提交。
数组里事务ID的最小值记为低水位,当前系统里面已经创建过的事务ID的最大值加1记为高水位。这个视图数组加高水位就组成了当前事务的一致性视图(read-view)。
而数据版本的可见性规则,就是基于数据的row trx_id和这个一致性视图的对比结果得到的。

图2 数据可见性规则
对于当前事务的启动瞬间来说,一个数据版本的row trx_id有以下几种可能:
- 如果落在绿色部分,表示这个版本是已经提交的事务或者是当前事务自己生成的,这个数据是可见的。
- 如果落在红色部分,表示这个版本是由将来启动的事务生成的,不可见。
- 如果落在橙色部分,就有两种情况:
- 若row trx_id在数组中,表示这个版本是由还没提交的事务生成的,不可见。
- 若row trx_id不在数组中,表示这个版本是已经提交了的事务生成的,可见。
比如图1中的数据来说,如果有一个事务,它的低水位是18,那么当它访问这一行数据时,就会从V4通过U3计算出V3,所以在它看来,这一行的值是11。
在更新时如何使用一致性读

图3 示例1
我们来看示例1,如果事务B在事务C更新之前查询,这个查询返回值是1。但是当它要去更新数据时,就不能在历史版本上更新了,否则事务事务C的更新就会丢失。
这里就用到一条规则:更新数据都是先读后写,而这个读只能是读当前的值,称为“当前读”(current read)。
因此事务B更新时,当前读拿到的数据是(1, 2),更新后是(1, 3),并且row trx_id是101。
事务B后续查询时,看到最新数据的版本号是101,而自己也是101,就直接返回,得到的k值是3。

图4 示例2
我们再来看示例2,示例2与示例1的区别在于,事务C'在事务B的写读操作后提交。
事务C'在提交前对行加写锁。而事务B是当前读,而且必须要加锁,因此被锁住了,必须等到事务C'释放这个锁,才能继续它的当前读。
到这里,把一致性读、当前读和行锁串起来了。
小结
本节问题,事务的可重复读隔离级别是如何实现的?
可重复读的核心就是一致性读;而事务更新数据的时候,只能用当前读。如果当前的记得的行锁被其他事务占用的话,就需要进入锁等待。
读提交
读提交的实现方式跟可重复读类似,它们最主要的区别是:
- 在可重复读隔离级别下,只需要在事务开始的时候创建一致性视图,之后事务里的其他查询都共用这个一致性视图;
- 在读提交隔离级别下,每个语句执行前都会重新算出一个新的视图。
参考资料
MySQL事务(二)事务隔离的实现原理:一致性读的更多相关文章
- MySQL事务和事务隔离级别
1.概述 事务就是对数据库数据进行更改(包括insert.update.delete等)操作的一个执行单元,通常有一条或多条更改语句组成.在同一个事务中的更改操作要么同时成功,要么同时失败. 事务具有 ...
- MySQL学习(三)MySQL锁与事务
本章我们着重讨论MySQL锁机制的特点,常见的锁问题,以及解决MySQL锁问题的一些方法或建议. 一.MySQL锁概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支 ...
- MySQL中的事务和MVCC
本篇博客参考掘金小册--MySQL 是怎样运行的:从根儿上理解 MySQL 以及极客时间--MySQL实战45讲. 虽然我们不是DBA,可能对数据库没那么了解,但是对于数据库中的索引.事务.锁,我们还 ...
- MySQL 一致性读 深入研究
一致性读,又称为快照读.使用的是MVCC机制读取undo中的已经提交的数据.所以它的读取是非阻塞的. 相关文档:http://dev.mysql.com/doc/refman/5.6/en/innod ...
- MySQL 一致性读 深入研究 digdeep博客学习
http://www.cnblogs.com/digdeep/p/4947694.html 一致性读,又称为快照读.使用的是MVCC机制读取undo中的已经提交的数据.所以它的读取是非阻塞的. 相关文 ...
- [MySQL] 一致性读分析
MySQL MVCC MySQL InnoDB存储引起实现的是基于多版本的并发控制协议---MVCC(Multi-Version Concurrency Control),基于锁的并发控制,Lock- ...
- 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?
在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...
- 第36讲 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景
在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...
- MySQL 温故知心(二) 事务的隔离级别
事务的隔离级别 A事务做了操作 没有提交 对B事务来说 就等于没做 获取的都是之前的数据但是 在A事务中查询的话 查到的都是操作之后的数据没有提交的数据只有自己看得到,并没有update到数据库 查看 ...
随机推荐
- AQS详解,并发编程的半壁江山
千呼万唤始出来,终于写到AQS这个一章了,其实为了写这一章,前面也是做了很多的铺垫,比如之前的 深度理解volatile关键字 线程之间的协作(等待通知模式) JUC 常用4大并发工具类 CAS 原子 ...
- 使用日志系统graylog获取Ceph集群状态
前言 在看集群的配置文件的时候看到ceph里面有一个graylog的输出选择,目前看到的是可以收集mon日志和clog,osd单个的日志没有看到,Elasticsearch有整套的日志收集系统,可以很 ...
- GreenDao增删改查
3.GreenDao增删改查 (1)插入 常用API //这是最简单的插入语句,新增一行数据,返回值为行号 public long insert(T entity) //传递一个数组,新增多行数据 p ...
- FairyGUI编辑器的和unity里的Obj对应关系
1.在FairyGUI官网上下载好unity的工程,用FairyGUI编辑器打开它的官方案例 2.在FairyGUI编辑器和Unity中,从一个最简单的示例"Bag"着手. ...
- 面试阿里,字节跳动99%会被问到的java线程和线程池,看完这篇你就懂了!
前言: 最近也是在后台收到很多小伙伴私信问我线程和线程池这一块的问题,说自己在面试的时候老是被问到这一块的问题,被问的很头疼.前几天看到后帮几个小伙伴解决了问题,但是问的人有点多我一个个回答也回答不过 ...
- CA证书与https讲解
最近面试问到这个问题,之前了解过但答的不是很好,再补充补充一下https方面的知识. 备注:以下非原创文章. CA证书与https讲解 1.什么是CA证书. ◇ 普通的介绍信 想必大伙儿都听说过介绍信 ...
- list scheduling algorithm 指令调度 —— 笔记
作者:Yaong 出处:https://www.cnblogs.com/yaongtime/articles/14033444.html 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作者同 ...
- 思维导图VS金字塔原理
作为常识,思维导图制作的核心元素是关键词,而金字塔原理制作的核心元素则是拓展的概要句子,这两种方式是当今人们常用的思维工具,本文对其做了对比,希望对你的选择有所帮助. 金字塔原理结构:从上到下三角形结 ...
- centons 7 清机 脚本
#/bin/bash##################################初始化系统###################setenforce 0 yum install -y yum- ...
- js 表格上checkbox 全选
<table class="layui-table"> <thead> <tr> <th width="75"> ...