热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

READCOMMITTED和REPEATABLEREAD事务隔离级别的对比与分析

在数据库事务处理中,InnoDB存储引擎提供了多种隔离级别,其中READCOMMITTED和REPEATABLEREAD是两个常用的选项。本文详细对比了这两种隔离级别的特点和差异,不仅从理论角度分析了它们对“脏读”和“幻读”的处理方式,还结合实际应用场景探讨了它们在并发控制和性能表现上的不同。特别关注了行锁机制在不同隔离级别下的行为,为开发者选择合适的隔离级别提供了参考。

经常会被问到 InnoDB隔离级别中 READ-COMMITED和REPEATABLE-READ 的区别,今天就整理了一下,不再从“脏读”、“幻读”这样的名词解释一样去回答了。

1. 行锁

InnoDB行锁实际锁的是索引记录,为了防止死锁的产生以及维护所需要的隔离级别,在执行sql语句的全过程中,innodb必须对所需要修改的行每条索引记录上锁。如此一来,如果你执行的 UPDATE 没有很好的索引,那么会导致锁定许多行:

update employees set store_id = 0 where store_id = 1;
---TRANSACTION 1EAB04, ACTIVE 7 sec
633 lock struct(s), heap size 96696, 218786 row lock(s), undo log entries 1
MySQL thread id 4, OS thread handle 0x7f8dfc35d700, query id 47 localhost root
show engine innodb status

上面的 employeesstore_id 列没有索引。注意 UPDATE 已经执行完成(没有提交),但依然有 218786 个行锁没有释放,还有一个undo记录。这意味着只有一行被更改,但却持有了额外的锁。堆大小(heap size)代表了分配给锁使用的内存数量。

在 REPEATABLE-READ 级别,事务持有的 每个锁 在整个事务期间一直被持有。

在 READ-COMMITED 级别,事务里面特定语句结束之后,不匹配该sql语句扫描条件的锁,会被释放。

下面是上述相同的 UPDATE 在 READ-COMMITED 级别下的结果:

---TRANSACTION 1EAB06, ACTIVE 11 sec
631 lock struct(s), heap size 96696, 1 row lock(s), undo log entries 1
MySQL thread id 4, OS thread handle 0x7f8dfc35d700, query id 62 localhost root
show engine innodb status

可以看到 heap size 没有变化,但是现在我们只持有一个行锁。无论什么隔离级别下,InnoDB 会为扫描过的每条索引记录创建锁,不同的是在 RC 模式,一旦语句执行完毕(事务未必完成),不符合扫描条件的记录上的锁会被随即释放。释放这些锁后,堆内存并不会马上释放,所以heap size看到与 RR 模式是一样的,但是持有的锁数量明显小了很多。

这也就意味着在 RC 级别下的事务A,只要A的UPDATE 语句 完成了,其它事务可以修改A中也扫描过的行,但在 RR 级别下不允许。

2. Read View

REPEATABLE-READ

在 REPEATABLE-READ 级别,read view 对象在事务一开启就被创建,这个一致性快照在整个事务期间一直保持打开。在同一个事务里,前后间隔几个小时执行一遍相同的 SELECT,你会得到完全一样的结果,这就是所谓的 MVCC (multiple version concurrency control),它是通过行版本号和UNDO段来实现的。

在 REPEATABLE-READ 级别, InnoDB会为范围扫描创建间隙锁(gap locks):

select * from some_table where id > 100 FOR UPDATE;

上面的update将会创建一个 gap lock,用来防止在 id>100 范围内有新行被插入,锁会持续到事务回滚或提交。比如在同一个事务里,上午5点执行 SELECT … FOR UPDATE,下午5点执行 UPDATE some_table where id>100,那么这个update只会修改上午5点 SELECT FOR UPDATE所锁定的行,因为大于100的记录的整个 间隙 被加了锁。

READ-COMMITED

在 READ-COMMITED 级别,read view 结构在每个语句开始的时候被创建,这意味着即使在同一个事务中,上午5点执行的 SELECT与下午5点执行的SELECT可能会得到不同的结果。因为 read view 在 READ-COMMITED 级别下仅在 语句执行 期间存在。

这就是所谓的 “幻读”(phantom read)。

READ-COMMITED 隔离级别下是没有gap locks,所以执行上面的 SELECT FOR UPDATE where id>100 并不会阻止其它事务插入新行,如果同一个事务里后面执行 UPDATE … where id>100,就有可能导致实际更新的行数比前面锁定的行数要多。

补充:
如果了解过 mysqldump 的实现原理,可知它就是充分利用InnoDB的MVCC特性,使用 REPEATABLE-READ 模式获取备份事务的一致性快照,避免锁表和幻读。

本文主要参考自 percona博客上的一篇文章 https://www.percona.com/blog/… 。

本文链接地址:http://seanlook.com/2016/09/0…


推荐阅读
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
  • 本文介绍了在CentOS 6.4系统中安装MySQL 5.5.37时遇到的启动失败和PID文件问题,并提供了详细的解决方案,包括日志分析、权限检查等步骤。 ... [详细]
  • 本题探讨了在一个有向图中,如何根据特定规则将城市划分为若干个区域,使得每个区域内的城市之间能够相互到达,并且划分的区域数量最少。题目提供了时间限制和内存限制,要求在给定的城市和道路信息下,计算出最少需要划分的区域数量。 ... [详细]
  • 本文详细介绍了如何在 MySQL 中授予和撤销用户权限。包括创建用户、赋予不同级别的权限(如表级、数据库级、服务器级)、使权限生效、查看用户权限以及撤销权限的方法。此外,还提供了常见错误及其解决方法。 ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 本文探讨了如何在 F# Interactive (FSI) 中通过 AddPrinter 和 AddPrintTransformer 方法自定义类型(尤其是集合类型)的输出格式,提供了详细的指南和示例代码。 ... [详细]
  • 探讨 HDU 1536 题目,即 S-Nim 游戏的博弈策略。通过 SG 函数分析游戏胜负的关键,并介绍如何编程实现解决方案。 ... [详细]
  • 深入理解BIO与NIO的区别及其应用
    本文详细探讨了BIO(阻塞I/O)和NIO(非阻塞I/O)之间的主要差异,包括它们的工作原理、性能特点以及应用场景,旨在帮助开发者更好地理解和选择适合的I/O模型。 ... [详细]
  • 本文概述了算法的基础概念,包括时间复杂度的计算规则,以及常见的递归算法的时间复杂度分析。同时,详细介绍了数组和链表的基本特性及其操作的时间复杂度,并提供了几个关于链表操作的具体示例。最后,探讨了栈和队列的概念及其应用,包括如何利用这些数据结构解决实际问题。 ... [详细]
  • CentOS系统安装与配置常见问题及解决方案
    本文详细介绍了在CentOS系统安装过程中遇到的常见问题及其解决方案,包括Vi编辑器的操作、图形界面的安装、网络连接故障排除等。通过本文,读者可以更好地理解和解决这些常见问题。 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 磁盘健康检查与维护
    在计算机系统运行过程中,硬件或电源故障可能会导致文件系统出现异常。为确保数据完整性和系统稳定性,定期进行磁盘健康检查至关重要。本文将详细介绍如何使用fsck和badblocks工具来检测和修复文件系统及硬盘扇区的潜在问题。 ... [详细]
  • 在跨浏览器开发中,一个常见的问题是关于如何在鼠标悬停时显示图片提示信息。本文深入探讨了 IE 浏览器对 IMG 元素 alt 属性的特殊处理,并提供了最佳实践建议。 ... [详细]
  • 本题探讨了在大数据结构背景下,如何通过整体二分和CDQ分治等高级算法优化处理复杂的时间序列问题。题目设定包括节点数量、查询次数和权重限制,并详细分析了解决方案中的关键步骤。 ... [详细]
author-avatar
溪边莎草
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有