概述

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

隔离级别

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

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

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

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

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

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

MVCC

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

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

如下图所示:

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 就是当前读

一致性非锁定读和锁定读

首先看看下面的图:

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和锁,准确点说就是一致性读和锁。

深度剖析 MySQL 事务隔离的更多相关文章

  1. [51CTO]新说MySQL事务隔离级别!

    新说MySQL事务隔离级别! 事务隔离级别这个问题,无论是校招还是社招,面试官都爱问!然而目前网上很多文章,说句实在话啊,我看了后我都怀疑作者弄懂没!本文所讲大部分内容,皆有官网作为佐证,因此对本文内 ...

  2. 查询mysql事务隔离级别

    查询mysql事务隔离级别 查询mysql事务隔离级别 分类: DB2011-11-26 13:12 2517人阅读 评论(0) 收藏 举报 mysqlsessionjava   1.查看当前会话隔离 ...

  3. MySQL事务隔离级别测试实例

    https://www.cnblogs.com/huanongying/p/7021555.html MySQL事务隔离级别 事务隔离级别 脏读 不可重复读 幻读 读未提交(read-uncommit ...

  4. Mysql事务-隔离级别

    MYSQL事务-隔离级别 事务是什么? 事务简言之就是一组SQL执行要么全部成功,要么全部失败.MYSQL的事务在存储引擎层实现. 事务都有ACID特性: 原子性(Atomicity):一个事务必须被 ...

  5. MySQL事务隔离级别 解决并发问题

    MySQL事务隔离级别 1. 脏读: 骗钱的手段, 两个窗口或线程分别调用数据库转账表,转账后未提交,对方查看到账后,rollback,实际钱没转. 演示方法: mysql默认的事务隔离级别为repe ...

  6. mysql事务隔离级别、脏读、幻读

    Mysql事务隔离级别本身很重要,再加上可能是因为各大公司面试必问的缘故,在博客中出现的概率非常高,但不幸的是,中国的技术博客要么是转载,要么是照抄,质量参差不齐,好多结论都是错的,对于心怀好奇之心想 ...

  7. mysql事务隔离级别与设置

    mysql数据库,当且仅当引擎是InnoDB,才支持事务: 1.隔离级别 事务的隔离级别分为:未提交读(read uncommitted).已提交读(read committed).可重复读(repe ...

  8. MySQL事务隔离级别(二)

    搞清楚MySQL事务隔离级别 首先创建一个表 account.创建表的过程略过(由于 InnoDB 存储引擎支持事务,所以将表的存储引擎设置为 InnoDB).表的结构如下: 为了说明问题,我们打开两 ...

  9. MySQL事务隔离级别(一)

    本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做 ...

随机推荐

  1. NOIP2007 矩阵取数游戏(区间DP)

    传送门 这道题第一眼看上去可能让人以为是贪心……不过贪心并不行,因为每次的操作是有2的幂次方的权值的.这样的话直接每次贪心最小的就目光短浅.所以那我们自然想到了DP. 据说这是一道很正常的区间DP? ...

  2. robotframework:appium切换webview后,在第一个页面操作成功,跳转到第二个页面后,执行命令失败

    问题: 在用robot写手机淘宝app的自动化时,打开手机淘宝后,点击天猫国际,跳转到天猫国际页面,天猫国际页面是H5, 需要切换到对应的webview,切换到webview后,点击美妆菜单,跳转到美 ...

  3. Python 赋值、浅拷贝和深拷贝

    初学Python,和C++还是有许多不同.直接赋值.浅拷贝和深拷贝,这三种拷贝对象的操作之间还是有许多的区别.Python语言的版本为2.7,在Pycharm中进行实验. 一.直接赋值 用下面的代码来 ...

  4. Cocos2d-x 3.2 创建新应用

    1.cd 到 Cocos2d-x 3.2 的目录: 2.python setup.py: 3.source /Users/netty/.bash_profile ; 4.cocos new TestP ...

  5. Django中的Ajax详解

    AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当 ...

  6. Moctf--Pubg题目

    假期举办的一场比赛,开始的题目比较基础,misc神马的都还好说,就是web有些坑了,比如我今天要写的这一道题目.不过大佬说很简单..不过最后我还是解出来了,把思路放在这里. 打开之后得到这个页面,在网 ...

  7. hdoj3664【DP】

    题意: 有一种值E=the number of elements where ai > i.比如1 3 2 4,只有3位置是满足的,E=1.然后他会给你一个数组和一个k,问有多少个序列的E=k. ...

  8. poj3069【贪心,水】

    妈蛋,题意看错-看了挑战时被标记的点还是给出的点,瞎搞了半个多小时... = =都想气的扔进水题系列了 #include <iostream> #include <cstdio> ...

  9. Template Code 无法使用 this.Host 报错

    问题显示: Error 6 Compiling transformation: 'Microsoft.VisualStudio.TextTemplatingBED07DAE3B6FD53FA94701 ...

  10. P5112 FZOUTSY

    传送门 没想到这题还这能用莫队--本来看看以为复杂度会挂的-- 预处理出每个字母开头往后\(k\)个的字符串的哈希值,然后大概就是那道小z的袜子了 而且据说这题的哈希得用自然溢出 //minamoto ...