转载于: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. PHP 两个多维数组根据某个键的值进行组合排序的几种思路(二)

    几个经过封装的方法: 1.使用 array_multisort() 函数 <?php $arr = [ ['name'=>'dee','age'=>28], ['name'=> ...

  2. java synchronized详解

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...

  3. boos直聘扫码直接登陆js代码

    <script type="text/javascript"> $(function () { function show_ts() { var Tishi = $(& ...

  4. const

     const int i = 20; int const i = 20; 这两个语句是完全相同的:const与int哪个写在前面都不影响语义. 所以: const int *p; int const ...

  5. 【leetcode】两数之和

    https://leetcode.com/problems/two-sum/ Example: Given nums = [2, 7, 11, 15], target = 9, Because num ...

  6. imx6 DDR_Stress_Test

    在调试DDR的时候,有时候需要更改参数.今天发现NXP提供了DDR Stress Test工具,用于DDR参数的校准. 参考链接 http://blog.csdn.net/qq405180763/ar ...

  7. Web测试的常用测试用例与知识

    1. Web测试中关于登录的测试 2. 搜索功能测试用例设计 3. 翻页功能测试用例 4. 输入框的测试 5. Web测试的常用的检查点 6. 用户及权限管理功能常规测试方法 7. Web测试之兼容性 ...

  8. LeetCode Total Hamming Distance

    原题链接在这里:https://leetcode.com/problems/total-hamming-distance/ 题目: The Hamming distance between two i ...

  9. ClearTrace

    一年前两次手动使用fn_trace_gettable对跟踪文件进行分析,按TextData排序,通过截取TextData左边N位尝试分组,观察总体相同的过程或语句中的关键字,逐一得出跟踪分析报表,罗列 ...

  10. oracle客户端安装配置 tnsnames.ora文件

    Oracle客户端tnsnames.ora连接配置 Oracle90的在C:\Oracle\ora90\network\ADMIN下面 Oracel10g的在D:\oracle\product\10. ...