高级玩家必备:深度剖析 MySQL 事务隔离!

栏目: 数据库 · 发布时间: 5年前

内容简介:每日早8点半,技术文章准时送上公众号后台回复“

点击上方 石杉的架构笔记 ,右上角选择“ 设为星标

每日早8点半,技术文章准时送上

公众号后台回复“ 学习 ”,获取作者独家秘制精品资料

往期文章

BAT 面试官是如何360°无死角考察候选人的(上篇)

每秒上万并发下的Spring Cloud参数优化实战

分布式事务如何保障实际生产中99.99%高可用

记一位朋友斩获 BAT 技术专家Offer的面试经历

亿级流量架构系列之如何支撑百亿级数据的存储与计算

本文来源:波波说运维

概述

今天主要分享下 MySQL 事务隔离级别的实现原理,因为只有InnoDB支持事务,所以这里的事务隔离级别是指InnoDB下的事务隔离级别。

高级玩家必备:深度剖析 MySQL 事务隔离!

隔离级别

  1. 读未提交 :一个事务可以读取到另一个事务未提交的修改。这会带来脏读,幻读,不可重复读问题

  2. 读已提交 :一个事务只能读取另一个事务已经提交的修改。其避免了脏读,仍然存在不可以重复读和幻读问题

  3. 可重复读 :同一个事务中多次读取相同的数据返回的结果是一样的。其避免了脏读和不可重复读问题,但是幻读依然存在

  4. 串行化 :事务串行之行。避免了以上所有问题

高级玩家必备:深度剖析 MySQL 事务隔离!

以上是SQL-92标准中定义的四种隔离级别。在MySQL中,默认的隔离级别是REPEATABLE-READ(可重复读),并且解决了幻读问题。

注: 不可重复读重点在于Update和delete,而幻读的重点在于insert。

MVCC

MVCC的全称是多版本并发控制。MVCC使得InnoDB的事务隔离级别下执行一致性读操作有了保证。

简单说就是为了查询一些正在被另一个事务更新的行,并且可以看到它们被更新之前的值。这是一个用来增强并发性的强大技术,可以使得查询不用等待另一个事务释放锁。

如下图所示:

高级玩家必备:深度剖析 MySQL 事务隔离!

MVCC会给每一行增加三个字段, 分别是: DB-TRX-ID、DB-ROLL-PTR、DB-ROW-ID

增删查改

在InnoDB中,给每行增加两个隐藏字段来实现MVCC,一个用来记录数据行的创建时间,另一个用来记录行的过期时间。

在实际操作中,存储的并不是时间,而是事务版本号,每开启一个新事务,事务的版本号就会递增。所以增删改查中对版本号的作用如下:

select: 读取创建版本小于或等于当前事务版本号,并且删除版本为空或大于当前事务版本的记录。这样可以保证在读取之前记录都是存在的 insert: 将当前事务的版本号保存至行的创建版本号 update 新插入一行,并以当前事务版本号作为新行的创建版本号,同时将原记录行的删除版本号设置为当前事务版本号 delete 将当前事务版本号保存至行的删除版本号 

快照读和当前读

  • 快照读 :读取的是快照版本,也就是历史版本

  • 当前读 :读取的是最新版版

普通的 select 就是快照读,而 update,delete,insert,select...LOCK In SHARE MODE,SELECT...for update 就是当前读

一致性非锁定读和锁定读

首先看看下面的图:

高级玩家必备:深度剖析 MySQL 事务隔离!

1、锁定读

在一个事务中,标准的SELECT语句是不会加锁,但是有两种情况例外。

  • SELECT ... LOCK IN SHARE MODE

  • SELECT ... FOR UPDATE

SELECT ... LOCK IN SHARE MODE:给记录假设共享锁,这样其他事务职能读不能修改,直到当前事务提交

SELECT ... FOR UPDATE:给索引记录加锁,这种情况跟UPDATE的加锁情况是一样的

2、一致性非锁定读

consistent read(一致性读),InnoDB用多版本来提供查询数据库在某个时间点的快照。

如果隔离级别是REPEATABLE READ,那么在同一个事务中的所有一致性读都读的是事务中第一个的读读到的快照;如果是READ COMMITTED,那么一个事务中的每一个一致性读都会读到它自己刷新的快照版本。

consistent read(一致性读)是READ COMMITTED和REPEATABLE READ隔离级别下普通SELECT语句默认的模式。一致性读不会给它锁访问的表加任何形式的锁,因此其他事务可以同时并发的修改它们

  1. Record Locks(记录锁):在索引记录上加锁

  2. Gap Locks(间隙锁) :在索引记录之间加锁,或者在第一个索引记录之前加锁,或者在最后一个索引记录之后加锁

  3. Next-Key Locks :在索引记录上加锁,并且在索引记录之前的间隙加锁。相当于Record Locks与Gap Locks的一个结合

假如一个索引包含以下几个值:10,11,13,20.那么这个索引的next-key锁将会覆盖以下区间:

(negative infinity, 10] (10, 11] (11, 13] (13, 20] (20, positive infinity) 

总结

在默认的隔离级别中,普通的SELECT用的是一致性读不加锁。而对于锁定读,UPDATE和DELETE,则需要加锁,至于加什么锁是有不同情况的。

如果对一个唯一索引使用了唯一的检索条件,那么只需要锁定相应的索引记录就好;如果是没有使用唯一索引作为检索条件,或者用到了索引范围扫描,那么将会使用间隙锁或者next-key锁来以此阻塞其他会话向这个范围内的间隙插入数据

利用MVCC实现一致性非锁定读,保证在同一个事务中多次读取相同的数据返回的结果是一样的,解决了不可重复读问题.

利用Gap Locks和Next-key可以阻止其他事务在锁定区间内插入数据,解决了幻读问题.

总之,MySQL的默认隔离级别的实现依赖于MVCC和锁,准确点说就是一致性读和锁。

END

如有收获,请划至底部,点击“ 在看 ”,谢谢!

推荐阅读:

更多文章:

欢迎长按下图关注公众号 石杉的架构笔记 ,后台回复“ 学习 ”,获取作者独家秘制精品资料

高级玩家必备:深度剖析 MySQL 事务隔离!

BAT架构经验倾囊相授

高级玩家必备:深度剖析 MySQL 事务隔离!


以上所述就是小编给大家介绍的《高级玩家必备:深度剖析 MySQL 事务隔离!》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Ext JS学习指南

Ext JS学习指南

(美)布莱兹、(美)拉姆齐、(美)弗雷德里克 / 孔纯、肖景海、张祖良 / 人民邮电出版社 / 2009-10 / 39.00元

《Ext JS学习指南》系统化地介绍了Ext JS的基础知识,从框架的下载安装到各种常用小部件的实例介绍,从如何自定义小部件到Ext JS代码复用和扩展机制,《Ext JS学习指南》覆盖了Ext JS知识的所有主要方面。作为Web 2.0时代企业应用的一把开发利器,Ext JS为企业应用开发的表现层实现提供了优秀的解决方案。 如果你掌握了HTML,并且了解一般的CSS和JavaScript的......一起来看看 《Ext JS学习指南》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

随机密码生成器
随机密码生成器

多种字符组合密码