MySQL事务隔离级别的实现原理

知识储备

  • 只有InnoDB支持事务,所以这里说的事务隔离级别是指InnoDB下的事务隔离级别
  • 隔离级别
    • 读未提交:一个事务可以读取到另一个事务未提交的修改。这会带来脏读,幻读,不可重复读问题
    • 读已提交:一个事务只能读取另一个事务已经提交的修改。其避免了脏读,仍然存在不可以重复读和幻读问题
    • 可重复读:同一个事务中多次读取相同的数据返回的结果是一样的。其避免了脏读和不可重复读问题,但是幻读依然存在
    • 串行化:事务串行之行。避免了以上所有问题

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

一致性非锁定读和锁定读

锁定读
  • 在一个事务中,标准的SELECT语句是不会加锁,但是有两种情况例外。SELECT ... LOCK IN SHARE MODE 和 SELECT ... FOR UPDATE。

    • SELECT ... LOCK IN SHARE MODE:给记录假设共享锁,这样其他事务职能读不能修改,直到当前事务提交
    • SELECT ... FOR UPDATE:给索引记录加锁,这种情况跟UPDATE的加锁情况是一样的
一致性非锁定读
  • consistent read(一致性读),InnoDB用多版本来提供查询数据库在某个时间点的快照。如果隔离级别是REPEATABLE READ,那么在同一个事务中的所有一致性读都读的是事务中第一个的读读到的快照;如果是READ COMMITTED,那么一个事务中的每一个一致性读都会读到它自己刷新的快照版本。Consistent read(一致性读)是READ COMMITTED和REPEATABLE READ隔离级别下普通SELECT语句默认的模式。一致性读不会给它锁访问的表加任何形式的锁,因此其他事务可以同时并发的修改它们

  • Record Locks(记录锁):在索引记录上加锁
  • Gap Locks(间隙锁):在索引记录之间加锁,或者在第一个索引记录之前加锁,或者在最后一个索引记录之后加锁
  • 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和锁,准确点说就是一致性读和锁

实例分析

客户端A

  • 客户端A开始一个事务,并以主键唯一索引作为检索条件进行更新

客户端B

  • 客户端B开始一个事务,由于客户端A已经开始了事务并以主键索引作为检索条件,所以会造成该索引被锁定。其他索引以及其他范围则不会被锁定可以正常操作

客户端A

  • 当客户端A重新开始一个事务并没有使用唯一索引作为检索条件

客户端B

  • 客户端B开始一个事务,由于客户端A的事务操作,那么mysql会使用next-key和间隙锁以此阻塞其他会话对表的操作

MySQL事务实现原理的更多相关文章

  1. Mysql 事务及其原理

    Mysql 事务及其原理 什么是事务 什么是事务?事务是作为单个逻辑工作单元执行的一系列操作,通俗易懂的说就是一组原子性的 SQL 查询.Mysql 中事务的支持在存储引擎层,MyISAM 存储引擎不 ...

  2. 深入学习MySQL事务:ACID特性的实现原理

    事务是MySQL等关系型数据库区别于NoSQL的重要方面,是保证数据一致性的重要手段.本文将首先介绍MySQL事务相关的基础概念,然后介绍事务的ACID特性,并分析其实现原理. MySQL博大精深,文 ...

  3. 一文说尽MySQL事务及ACID特性的实现原理

    MySQL 事务基础概念 事务(Transaction)是访问和更新数据库的程序执行单元:事务中可能包含一个或多个 sql 语句,这些语句要么都执行,要么都不执行.作为一个关系型数据库,MySQL 支 ...

  4. MySQL事务原理浅析

    前言​ 因为自己对数据的可靠性,可用性方面特别感兴趣,所以在MySQL事务方面看了很多资料,也看了很多博客,所以想到自己也写一篇博客整理整理自己所学内容,尽量用自己的语言解释得通俗易懂. 事务经典场景 ...

  5. mysql事务原理及MVCC

    mysql事务原理及MVCC 事务是数据库最为重要的机制之一,凡是使用过数据库的人,都了解数据库的事务机制,也对ACID四个 基本特性如数家珍.但是聊起事务或者ACID的底层实现原理,往往言之不详,不 ...

  6. 面试刷题29:mysql事务隔离实现原理?

    mysql的事务是innodb存储引擎独有的,myisam存储引擎不支持事务. 事务最经典的例子就是转账了,事务要保证的是一组数据库的操作要么全部成功,要么全部失败.是为了保证高并发场景下数据的正确性 ...

  7. MySQL事务(二)事务隔离的实现原理:一致性读

    今天我们来学习一下MySQL的事务隔离是如何实现的.如果你对事务以及事务隔离级别还不太了解的话,这里左转. 好的,下面正式进入主题.事务隔离级别有4种:读未提交.读提交.可重复读和串行化.首先我们来说 ...

  8. 个人MySQL的事务特性原理学习笔记总结

    目录 个人MySQL的事务特性原理笔记总结 一.基础概念 2. 事务控制语句 3. 事务特性 二.原子性 1. 原子性定义 2. 实现 三.持久性 1. 定义 2. 实现 3. redo log存在的 ...

  9. 详解MySQL事务原理

    老刘是即将找工作的研究生,自学大数据开发,一路走来,感慨颇深,网上大数据的资料良莠不齐,于是想写一份详细的大数据开发指南.这份指南把大数据的[基础知识][框架分析][源码理解]都用自己的话描述出来,让 ...

随机推荐

  1. SlidesJS基本使用方法和官方文档解释

    Slides – 是一个简单的,容易定制和风格化,的jQuery幻灯片插件. Slides提供褪色或幻灯片过渡效果,图像淡入淡出,图像预压,自动生成分页,循环,自动播放的自定义等很多选项. 用Slid ...

  2. Replication--复制笔记1

    1.快照复制和事务复制使用分发代理传递文件,而合并复制使用合并代理来传递文件2.快照代理在分发服务器上运行3.在创建快照是,根据复制的类型对发布表的加锁方式而不同    a)对应合并发布,快照代理不适 ...

  3. Jenkins Pipeline+Maven+Gitlab持续集成构建问题集锦

    问题 1.全局配置一定要写正确,之前where git 给的地址时E:\Git\cmd\git.exe一直报错,其实Windows真正的git.exe在bin目录下 如果是Linux中,使用where ...

  4. centos 安装erlang rpm包互相依赖问题

    在项目中使用 centos 6.5 mini 版本(网络隔离,无法上外网),因测试需要使用到 erlang 环境. erlang rpm 包下载地址:https://www.erlang-soluti ...

  5. ASP.NET Core2.0杂项

    一.添加自定义的路由. 1.1.默认的路由添加语句 Startup文件的ConfigureServices方法中添加: services.AddMvc();//添加MVC的服务 1.2 添加自定义的路 ...

  6. jquery事件二 -- 选项卡,失去焦点

    以之前的选项卡例子为原版,当选上某一个选项卡的时候,选项卡周围会有一个蓝色的边框影响视觉体验,那么应该怎么去掉这个边框色呢?只需要加一行blur()--失去焦点函数就可以了 <!DOCTYPE ...

  7. 如何 3D 打印一个密码锁

    简评:这篇文章介绍怎么用 3D 打印机做一个密码锁,巧妙地利用机械结构的变化实现锁的功能,相当有趣! 3D 打印机非常适合打印静态物体.如果你够聪明,还可以打印出功能物件.如果你特别特别聪明,那你能做 ...

  8. miniui中表单验证规则总结

    页面链接: http://www.miniui.com/demo/#src=form/rules.html 页面效果图: 页面代码: <!DOCTYPE html PUBLIC "-/ ...

  9. js中的类和对象以及自定义对象

    js中的类 1.类的声明 function Person(name,age){ this.name=name; this.age=age; this.test=function(a){ alert(a ...

  10. js中奇怪的问题 同步ajax,modal遮罩层

    奇怪问题一 今天有一段js执行的时候出现了问题 $.ajax({ ..., async:false, ... }); $('#myModal').modal('hide'); loadcurrentp ...