深入解析MySQL的事务隔离及其对性能产生的影响

 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-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。
  •          幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

         在MySQL中,实现了这四种隔离级别,分别有可能产生问题如下所示:

20151219142625513.jpg (838×267)


MySQL事务隔离级别对其性能的影响
MySQL默认工作在级别三下。我们知道事务隔离是为了避免并发操作相互影响而导数据的不一致性。所以为了保证数据的一致性,就引入了事务隔离的功能。以上四个级别的对数据的一致性保护是逐步提高的。级别4对事务的隔离效果最好,但是性能最差,一般不再生产环境中使用。
下面通过实例来检验不同级别下MySQL性能收到的影响。我的实验环境是:Redhat5.8+MySQL5.5
首先我们这里启用两个session:
1、验证级别一的特性
我们在session A上进行的操作为:

20151219142742629.jpg (439×108)

在session B上的操作同session A,这里不再附上截图。
       接下来我们就通过一系列的实验来观察READ-UNCOMMITTED到底是什么,它到底有什么特性,对我们的操作到底有什么影响。首先,我们可以看到表中的初始数据如下:

20151219142759392.jpg (396×309)

接下来我们在sessionA上更改其中的一条记录,更改结果如下:

20151219142836127.jpg (449×393)

注意:我们在上面启用了事务,但是我们在这里并没有进行commit操作。
 
接下来我们在sessionB中对刚才改过的表进行select查询,查询结果如下:

20151219142857081.jpg (393×258)

我们可以清楚的看到,虽然我们并没有对session A的结果进行commit,但是结果确实已经改变。因此在这种级别下,没有提交的操作会对数据的一致性有影响。因此,如果我们此时在session A上对上述操作进行回滚,我们会发现此时session B上的结果又回到原来最初的结果,这样就造成了数据的不一致性,这也称为数据的幻读现象,看起来是很诡异的事情。因此在某些场景下,我们应该避免这种现象的产生。但是这种级别也不是没有它的用武之地,比如当我们有大量数据需要写入,而读操作很少的时候,就适合用这种模式。
可以看到session A回滚后,session B中的数据又变成最初的样子,这也称为幻读:

20151219142930549.jpg (388×285)

2、验证级别READ COMMITTED特性
       首先把session A和session B的隔离级别都改为READ-COMMITTED,并且全部都开启事务,操作如下:

20151219142953399.jpg (419×106)

接下来我们查看tutors表的初始状态信息:

20151219143009635.jpg (389×273)

然后我们依然是对数据进行更新操作,更新之后仍然没有commit。我们可以看到在sessionA中,结果已经发生改变:

20151219143025324.jpg (447×356)

此时我们在session B中查看,发现结果依然维持不变:

20151219143041273.jpg (400×274)

但是,如果我们此时在session A中进行commit操作,我们就会发现,sessionB此时查询就会发生改变,这样也造成了数据的前后不一致性,也是数据的幻读:

20151219143129621.jpg (387×272)

3、数据的可重读
       数据的可重读,也叫作REPEATABLE-READ,这是MySQL默认采用的事务隔离级别,有其优势,但是仍然没有从根本上解决数据的一致性问题。首先,还是让我们来测试一下,在这种级别下MySQL到底是如何工作的,又有哪些特性,我们又该怎样去操作。
       我们先把REPEATABLE-READ的环境设置好,具体的操作方法如下:

20151219143145636.jpg (426×103)

然后我们在查看其初始数据,其结果如下:

20151219143201861.jpg (391×281)

我们在session A中修改数据,并进行commit,修改后的结果如下:

20151219143219960.jpg (394×285)

然后我们在session B中进行查看发现结果仍然没有任何改变:

20151219143235949.jpg (383×282)

这就是可重读的特性,只要本次会话不提交,尽管对方修改,但是结果仍然不变,只有在session B中也进行commit操作,所作的修改才会在sessionB中生效。
 
4、seriabliable
这个级别是事务隔离安全性最好的,但是也是性能最差的,因为这个级别所有的操作都是串行进行的。一个操作没有提交,另一个受到影响的操作会处于阻塞状态。
为了验证这种效果,我们先把环境设置好,具体为在session A和session B同时设置如下:

20151219143252378.jpg (400×100)

在session A 中对其任意字段进行修改,并且没有进行commit操作。此时挥发现sessionB中的查询操作会一直处于阻塞状态:

20151219143310329.jpg (298×55)

这就设串行化隔离的效果,也是为什么串行化隔离并发能力差的原因。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


本篇内容主要讲解“sqlalchemy的常用数据类型怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“sqlalche...
今天小编给大家分享一下sqlServer实现分页查询的方式有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家
这篇文章主要介绍“sqlmap之osshell怎么使用”,在日常操作中,相信很多人在sqlmap之osshell怎么使用问题上存在疑惑,小编查阅了各式资料,整理出
本篇内容介绍了“SQL注入的知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...
1. mssql权限sa权限:数据库操作,文件管理,命令执行,注册表读取等system。是mssql的最高权限db权限:文件管理,数据库操作等 users-administratorspublic权限:数据库操作 guest-users2、sql server注入执行命令查
sql执行计划如何查看?在SPL庞大的数据中我们不知道如何查看实际数据库中发生了什么事情,有必要定期进行查询优化和索引否则会影响我们后期的SQL的查询速度。那么针对这样的问题我们必须要知道SQL执行的计划,在本文中winwin7小编给大家分享下SQL执
SQL Server 是Microsoft 公司推出的关系型数据库管理系统。具有使用方便可伸缩性好与相关软件集成程度高等优点应用非常广泛。不过在使用中,我们会遇到非常多的错误,面对这么庞大的数据库环境,当然会有精确的错误代码的对照季,下面小编分享的
SQL Server本地账户无法登陆出现错误提示:error:40-Could not open a connenction to SQL Server的问题很常见,对于初学者来说可能不知道如何解决,一起来看看下面的解决方案。解决步骤如下:1、这种情况需要开启 SQL Server service
微软推出的SQL2008是一款非常好用的数据库软件,它稳定、功能强大,为众多企业提供了最佳的数据库解决方案,那么我们如何在Windows中安装它呢,一些朋友对SQL Server 2008的安装过程还不是很熟悉,下面就一起来看看SQL Server 2008详细安装图解...
本页概要如果您使用的是 SQL Server 2005备份和还原Sp_detach_db 和 Sp_attach_db 存储过程关于排序规则的说明导入和导出数据(在 SQL Server 数据库之间复
DBCC CHECKIDENT 检查指定表的当前标识值,如有必要,还对标识值进行更正。 语法 DBCC CHECKIDENT ( 'table_name' [ , { NORESEED
这里对 SQL Server 字符串函数进行分门别类地列出,便于查阅和记忆,相信大家都在其它方面有高深的编程基础,从字面上来说大家都知道这些函数的意义,就不对这些函数作过多的解释了,主要谈些经验,具体
查询及删除重复记录的方法 1、查找表(people)中多余的重复记录,重复记录是根据单个字段(peopleId)来判断select*frompeoplewherepeopleIdin(selectpe
微软发SQL Server 2008第二个CTP预览版from: http://news.csdn.net/n/20070807/107158.html8月7日消息,微软公司本周发布了SQL Serv
症状当您将数据库备份恢复到另一台服务器时,可能会遇到孤立用户的问题。SQL Server 联机丛书中的孤立用户疑难解答主题中没有讲述解决此问题的具体步骤。本文介绍了如何解决孤立用户问题。更多信息虽然术
当登录SQL Server 2005时可能碰到错误: 'No Process is on the Other End of the Pipe'。解决方法:(1)Open up SQL
概要本文描述如何映射标准登录和集成登录来解决在运行 SQL Server 的服务器之间移动数据库时的权限问题。更多信息当您将数据库从一个运行 SQL Server 的服务器移到另一个运行 SQL Se
----------------------------------------问题:该用户与可信的SQL SERVER 连接无关联使用sa用户或自建用户使用“SQL SERVER 身份认证”连接数据
更新日期: 2007 年 5 月 20 日 使用下表可以确定各种版本的 Microsoft SQL Server 2005 支持哪些功能。有关 SQL Server 2005 Enterprise E
当从Excel导入数据到Sql Sever中,可能会出现以下问题:
对于指定的缓冲区大小而言,源列的数据太大