热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

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

这篇文章主要介绍了MySQL的事务隔离及其对性能产生的影响,在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)

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

推荐阅读
  • 七大策略降低云上MySQL成本
    在全球经济放缓和通胀压力下,降低云环境中MySQL数据库的运行成本成为企业关注的重点。本文提供了一系列实用技巧,旨在帮助企业有效控制成本,同时保持高效运作。 ... [详细]
  • H5技术实现经典游戏《贪吃蛇》
    本文将分享一个使用HTML5技术实现的经典小游戏——《贪吃蛇》。通过H5技术,我们将探讨如何构建这款游戏的两种主要玩法:积分闯关和无尽模式。 ... [详细]
  • 软件测试行业深度解析:迈向高薪的必经之路
    本文深入探讨了软件测试行业的发展现状及未来趋势,旨在帮助有志于在该领域取得高薪的技术人员明确职业方向和发展路径。 ... [详细]
  • Django与Python及其他Web框架的对比
    本文详细介绍了Django与其他Python Web框架(如Flask和Tornado)的区别,并探讨了Django的基本使用方法及与其他语言(如PHP)的比较。 ... [详细]
  • ABP框架是ASP.NET Boilerplate的简称,它不仅是一个开源且文档丰富的应用程序框架,还提供了一套基于领域驱动设计(DDD)的最佳实践架构模型。本文将详细介绍ABP框架的特点、项目结构及其在Web API优先架构中的应用。 ... [详细]
  • 本文讲述了一位80后的普通男性程序员,尽管没有高学历,但通过不断的努力和学习,在IT行业中逐渐找到了自己的位置。从最初的仓库管理员到现在的多技能开发者,他的职业生涯充满了挑战与机遇。 ... [详细]
  • 本文详细介绍了 Java 网站开发的相关资源和步骤,包括常用网站、开发环境和框架选择。 ... [详细]
  • 解决ADODB连接Access时出现80004005错误的方法
    本文详细介绍了如何解决在使用ADODB连接Access数据库时遇到的80004005错误,包括错误原因分析和具体的解决步骤。 ... [详细]
  • 搭建个人博客:WordPress安装详解
    计划建立个人博客来分享生活与工作的见解和经验,选择WordPress是因为它专为博客设计,功能强大且易于使用。 ... [详细]
  • 本文详细介绍了PostgreSQL与MySQL在SQL语法上的主要区别,包括如何使用COALESCE替代IFNULL、金额格式化的方法、别名处理以及日期处理等关键点。 ... [详细]
  • flea,frame,db,使用,之 ... [详细]
  • 本文详细探讨了在Web开发中常见的UTF-8编码问题及其解决方案,包括HTML页面、PHP脚本、MySQL数据库以及JavaScript和Flash应用中的乱码问题。 ... [详细]
  • 本文探讨了在MySQL数据库中处理大规模数据删除的最佳实践,包括分批删除、利用索引、管理事务以及选择合适的删除命令等策略,旨在提升删除效率并确保系统稳定。 ... [详细]
  • HTML前端开发:UINavigationController与页面间数据传递详解
    本文详细介绍了如何在HTML前端开发中利用UINavigationController进行页面管理和数据传递,适合初学者和有一定基础的开发者学习。 ... [详细]
  • PHP面试题精选及答案解析
    本文精选了新浪PHP笔试题及最新的PHP面试题,并提供了详细的答案解析,帮助求职者更好地准备PHP相关的面试。 ... [详细]
author-avatar
hustjs
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有