数据库隔离级别的由来 及其与MVCC的关系

本贴最后更新于 3047 天前,其中的信息可能已经沧海桑田

我们都知道根据SQL92标准,关系数据库有四个隔离级别:脏读,读未提交,可重复读,可序列化。但这几个隔离级别是怎么来的?我们来扯扯把

 

如果数据库像Redis一样是单线程 串行处理所有的事务的话,我们就没有隔离级别这茬事了,或者说隔离级别都是最高的 可序列化。但是我们知道,数据库是一个磁盘IO很高的系统,尤其是用机械硬盘的时候,如果串行处理事务,那么就会导致磁盘不断寻道,处理效率低下。因此积攒一堆读写然后批量读取写入机械磁盘这会大大提高数据库的吞吐量。再加上现在CPU都这么多个核,多线程是必不可少了。

 

但多线程会带来一个问题,就是并发。你想象一下,在一个事务A里,你根据事务B未提交的记录做了一个判断并写了数据库,然后B回滚了,你会有怎样的心情~~于是乎数据库系统决定帮助你处理这个问题,提出了各种层次的隔离级别,让你读取数据的时候感觉就像只有自己在访问数据库一样。(NOSQL产品则没有这些隔离级别,甚至也没有ACID中的A-原子性,因此他们数据之间的关联关系很少,易于水平扩展,要扩展性能的话,加机器就可以了,但有得有失,用NOSQL实现复杂逻辑的时候 就要自己处理掉 事务的原子性,并发时候的脏读 等问题。)

 

数据库决定要让我们读取数据的时候感觉就像只有自己在访问数据库一样,要怎么搞呢?我们先从单线程处理所有事务的场景里开始着手,看看哪里可以改进变成并发把。

 

当两个事务里完全没有处理相同的记录的情况下,他们是天然可并发,无需额外处理。但是如果两个事务里存在相同的记录怎么办?我们分析下,对于同一条数据库记录,在不同的事务中仅存在以下几种关系:

一个事务读了,后续的另一个事务要读,简称读读

一个事务读了,后续的另一个事务要写,简称读写

一个事务写了,后续的另一个事务要读,简称写读

一个事务写了,后续的另一个事务要写,简称写写

 

先看读读,哎,好像天然可并发,怎么搞看起来都是像只有自己在访问数据库一样,棒棒哒。略过。

再看读写,第一个事务读过了,然后第二个事务要写,如果允许写的话,第一个事务不就蒙B了,这哪里是我一个人在访问数据库?!好吧,这样的话 ,根据我们程序员最直观的思维,给这条记录加个锁就好啦(行锁),每条读取的记录都要上锁。上锁后其他事务就不得读取这条记录了,除非等第一个事务完结。但这样读读关系不能并行了,于是大家都想,读读而已呀,这必须能并行呀,能提高不少性能呢。于是乎程序猿们继续发挥聪明才智,设计了读写锁~读读可并行,读写不可并行,这样就OK啦,大大提高了并行的效率。

这个做法嘛,对应的就是我们数据库隔离级别里的 可重复读。这个可重复读嘛,有一个BUG,就是所谓的 幻象读(不知道怎么能起到这么一个名字….)。这个BUG的原因如下:行锁是基于已有记录的,但如果记录不存在的话,怎么搞?如:数据库里只有2条记录,id分别为1、2;事务A第一次执行语句select * from user where id<3 有2条结果,并对这两条记录加了锁,但因没有第三条记录,所以无法加行锁。这时另外一个事务B插入了一条记录把id=3的记录插进去并提交了,那么事务A再次执行上述SQL的时候就会得到与第一次不一样的结果。看来可重复读….其实也并不可重复….

 

虽然引入了读写锁的机制后,数据库性能得到了大大的提升,但是人类追求效率的心是永无止境的,现在在上述 几个关系中,已经实现了 读读关系 并行处理了,那么其他关系能并行么?

现在有读锁和写锁,如果允许某个读锁升级成写锁的话,那么 读写关系也可以并行了,这个时候带来的负面效果是 之前一同获得读锁的事务们 再次读取这条记录的时候,有可能读到 获得写锁的事务更新的数据,于是这个隔离级别我们就称为 读已提交。

 

再继续放松限制,完全去掉读锁,也就使得 写读 也能并行了,这时候,数据库隔离级别就变成 读未提交。这时候保留的写锁,是为了保持ACID中的A,让其能回滚。

 

基于上述的实现方式,专家们定义了4种隔离级别。可见,这个隔离级别并没有其他特殊的含义,仅仅是局限于当时的技术实现形式而已。

 

在后来出现了MVCC这种基于复制记录形式的并发处理形式(具体实现自行再百度吧),指定隔离级别的专家们就蒙B了,MVCC可以做到比 可重复读更高的隔离级别(没有幻象读),且在读多些少的场景下实现比 行锁 机制里 读已提交,可重复读 更高的效率。

但由于 隔离级别在之前已经深入人心了,甚至于有些程序还利用了RC的特性来编写了程序,因此基于MVCC实现的数据库通常也会对应回四种隔离级别:可序列化(不使用MVCC),可重复读(使用MVCC,对应于SQL92里的可重复读,但不会出现幻象读),读已提交(故意减少MVCC的隔离程度,映射回RC这个隔离级别,这种实现相对于RR或许会更消耗数据库性能),以及读未提交。

大家普遍存在一个误区,隔离级别越高,数据库性能越差,这在行锁对应的数据库实现里,是正确的。但在MVCC里可就不一定了,个人认为RR的性能会比RC高,或者至少相差无几。

 

嗯~写完,OVER~

  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    333 引用 • 619 回帖
  • 一致性
    10 引用 • 5 回帖
  • MVCC
    4 引用 • 4 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 624 关注
  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 650 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    186 引用 • 318 回帖 • 331 关注
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    77 引用 • 159 回帖
  • sts
    2 引用 • 2 回帖 • 167 关注
  • 安全

    安全永远都不是一个小问题。

    191 引用 • 813 回帖
  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    85 引用 • 122 回帖 • 619 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    7040 引用 • 31847 回帖 • 218 关注
  • V2Ray
    1 引用 • 15 回帖 • 2 关注
  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    713 引用 • 1174 回帖 • 104 关注
  • 服务

    提供一个服务绝不仅仅是简单的把硬件和软件累加在一起,它包括了服务的可靠性、服务的标准化、以及对服务的监控、维护、技术支持等。

    41 引用 • 24 回帖 • 1 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 97 关注
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 383 回帖 • 1 关注
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    324 引用 • 1395 回帖 • 1 关注
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖 • 4 关注
  • 学习

    “梦想从学习开始,事业从实践起步” —— 习近平

    163 引用 • 473 回帖 • 1 关注
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖 • 1 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    10 引用 • 88 回帖 • 1 关注
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 248 回帖 • 123 关注
  • 招聘

    哪里都缺人,哪里都不缺人。

    189 引用 • 1056 回帖
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    19 引用 • 31 回帖 • 2 关注
  • 安装

    你若安好,便是晴天。

    131 引用 • 1184 回帖
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖 • 3 关注
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖 • 1 关注
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 24 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    21 引用 • 37 回帖 • 523 关注