转载于:http://blog.csdn.net/wudongxu/article/details/8623610

SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。

Read Uncommitted(读取未提交内容)

在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

Read Committed(读取提交内容)

这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

Repeatable Read(可重读)

这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读(Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control 间隙锁)机制解决了该问题。注:其实多版本只是解决不可重复读问题,而加上间隙锁(也就是它这里所谓的并发控制)才解决了幻读问题。

Serializable(可串行化)

这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

不可重复读(Non-repeatableread):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新了原有的数据。

幻读(Phantom Read):当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。事务第一次读的行范围显示出其中一行已不复存在于第二次读或后续读中,因为该行已被其它事务删除。同样,由于其它事务的插入操作,事务的第二次或后续读显示有一行已不存在于原始读中。幻读其实也应该算是一种不可重复读现象,只是它只是相对于insert和delete操作,而上面的不可重复读现象但注重的是update操作。这里这样称呼的原因是insert的新的row是没有版本信息的,它要通过一个范围来确定。

注:这里的客户端也是一个事务。

set sessiontransaction isolation level read uncommitted;

set autocommit=0;

脏读的演示:

客户端1

图1

客户端2

图2

通过上面两张图可以清楚的看到当tx_isolation=readuncommitted的时候,当一个事务(事务1)修改了数据但并没有提交的时候,另外的事务(事务2)是可以访问到该修改的数据。而此时如果前一个事务又取消了之前的修改(rollback)的时候,那么事务2得到的数据就是一个“脏”数据。下面我们看一下read committed是否有会这种情况。

客户端1

图3

图4

通过图3可以看到即客户端2 update了(但还没commit),此时客户端1读到的还是之前的数据,当客户端2真正的commit之后,客户端1才能读到更新后的数据。另外通过图3我们同时可以看到另一个现象,不可重复读,即在一个事务内(客户端1)两次读取的数据不一致。下面我们看一下在Repeatable Read级别下是否有该现象。

Repeatable Read可重复读

图5

图6

通过图5可以看到即使客户端2commit之后但客户端1还没commit的话,那么在该事务内的任何时候,访问同一条记录的结果都是一样的。所以repeatable read不存在不可重复读问题。

幻读:其实跟不可重复读差不多,只是幻读指的是行记录数(一个范围),而不可重复读相对的是一条记录。如在事务1里第一次读取这个范围的记录数为10条,但另一个事务删除了这个范围内的某一条记录,这时就会导致事务2的再次读取与第一次读取的结果不一致。Innodb通过MCVV+间隙锁解决了这个问题。所以对于innodb在repeatable read等级上也不会出现幻读。当前串行化更不会出现上面的问题,因为

事务串行化

图7

图8

注:上面的注释序号表示操作或结果的出现顺序。事务1先于事务2执行。通过图7,8可以看到当事务1 select了表tx_test之后,事务2的update被阻塞了(因为存在一个共享锁),只有当事务1 commit之后update才真正的被执行,同时此时tx_test又被事务2所占有(排它锁),所以客户1(事务3) select也被阻塞了,只有在

事务2 commit之后才得以执行。

MVCC是为了减少加锁而引入了,从而来提高并发性。MVCC只工作在repeatable read和read commit两个隔离级别。而read uncommitted则是每次只管读最新的版本的数据行,serializable则会对每个读取操作加锁,所以也不需要MVCC。

上面就是innodb支持的4种隔离级别,以及它们存在的问题。同时我们通过实验验证了这些问题。

参考资料:

《高性能mysql》第二版

 

InnoDB事务隔离级别的更多相关文章

  1. InnoDB 事务隔离级别

    InnoDB是一种平衡高可靠性和高性能的通用存储引擎.在MySQL数据库5.5.8版本开始,InnoDB是默认的MySQL存储引擎. InnoDB的主要优势 - 其DML操作遵循ACID,具有提交,回 ...

  2. Innodb中的事务隔离级别和锁的关系

    前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力. ...

  3. Innodb中的事务隔离级别和锁的关系(转)

    原文:http://tech.meituan.com/innodb-lock.html 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库 ...

  4. innodb是如何巧妙实现事务隔离级别

    之前的文章mysql锁机制详解中我们详细讲解了innodb的锁机制,锁机制是用来保证在并发情况下数据的准确性,而要保证数据准确通常需要事务的支持,而mysql存储引擎innodb是通过锁机制来巧妙地实 ...

  5. MySQL InnoDB中的事务隔离级别和锁的关系

    前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力. ...

  6. InnoDB锁问题 & DB事务隔离级别

    <参考:http://www.cnblogs.com/jack204/archive/2012/06/09/2542940.html>InnoDB行锁实现方式InnoDB行锁是通过给索引上 ...

  7. 重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系

    重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系 Innodb中的事务隔离级别和锁的关系 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁 ...

  8. Innodb 中的事务隔离级别和锁的关系

    转自:https://tech.meituan.com/innodb-lock.html 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据 ...

  9. Innodb中的事务隔离级别和锁的关系(转载)

    nodb中的事务隔离级别和锁的关系 原文:https://tech.meituan.com/innodb-lock.html ameng ·2014-08-20 15:50 前言: 我们都知道事务的几 ...

随机推荐

  1. Yii源码阅读笔记(三十五)

    Container,用于动态地创建.注入依赖单元,映射依赖关系等功能,减少了许多代码量,降低代码耦合程度,提高项目的可维护性. namespace yii\di; use ReflectionClas ...

  2. Virtualbox 虚拟机支持硬件摄像头

    最近我们公司做了一个摄像头项目,需要测试各种浏览器的情况,我就安装了一个Win xp的虚拟机,但是发现无法找到摄像头,经过查阅资料找到了解决办法 前提环境 Mac电脑 Virtualbox 虚拟机 虚 ...

  3. freebsd 系统时间

    http://blog.csdn.net/wowoto/article/details/5557810 https://www.douban.com/note/150233427/ date #查看当 ...

  4. Nginx配置加入css缓存配置后,css等文件not found

    现在配置: location / { root /root/html/product; } Probably another block had definition for the static f ...

  5. JMeter学习-022-JMeter 分布式测试(性能测试大并发、远程启动解决方案)

    在使用 JMeter 进行性能测试时,难免遇到要求并发请求数比较的场景,此时单台测试机的配置(CPU.内存.带宽等)可能无法支持此性能测试场景.因而,此时 JMeter 提供的分布式测试功能就有了用武 ...

  6. 前台获取Dropdownlist选中的text

    $("#ddltest").find("option:selected").text()

  7. Open Close Principle 开闭合原则

  8. SQL 数据分页查询

    最近学习了一下SQL的分页查询,总结了以下几种方法. 首先建立了一个表,随意插入的一些测试数据,表结构和数据如下图: 现在假设我们要做的是每页5条数据,而现在我们要取第三页的数据.(数据太少,就每页5 ...

  9. NDK开发-零散知识点整理

    JavaVM 标准Java平台下,每一个Process可以产生很多JavaVM对象,但在Android平台上,每一个Process只能产生一个Dalvik VM对象,也就是说在Android进程中是通 ...

  10. centos下安装java8

    http://tecadmin.net/install-java-8-on-centos-rhel-and-fedora/#