三分钟图解事务隔离级别,看一遍就懂

前文说过,”锁” 是数据库系统区别于文件系统的一个关键特性,其对象是 事务,用来锁定的是数据库中的对象,如表、页、行等。锁确实提高了并发性,但是却不可避免地存在一些潜在的 并发一致性问题

不过好在锁只会带来四种问题(丢失更新、脏读、不可重复读、幻读),如果可以防止这四种情况的发生,那将不会产生并发异常。为此,ISO 和 ANIS SQL 标准制定了四种 事务隔离级别标准,用来对应地解决锁带来的几种问题。

锁带来的四种并发一致性问题

丢失更新 Last To Modify

缺少更新很容易理解。简单地说,一个事务的更新操作会被另一个事务的更新操作覆盖,导致数据不一致。

[En]

Missing updates is easy to understand. To put it simply, * the update operation of one transaction will be overwritten by the update operation of another transaction, resulting in data inconsistency.*

举个例子:

1)事务 T1 将行记录 r 更新为 v1,但是事务 T1 并未提交

2)与此同时,事务 T2 将行记录 r 更新为 v2,事务 T2 未提交

3)事务 T1 提交

4)事务 T2 提交

如下图所示,显然,事务 T1 丢失了自己的修改。

三分钟图解事务隔离级别,看一遍就懂

但事实上,这并不完全会发生。

[En]

But, in fact, this is not exactly going to happen.

因为我们说过对于行进行更新操作的时候,需要对行或其他粗粒度级别的对象加锁,因此当事务 T1 修改行 r 但是没提交的时候,事务 T2 对行 r 进行更新操作的时候是会被阻塞住的,直到事务 T1 提交释放锁。

所以, 从数据库层面来讲,数据库本身是可以帮助我们阻止丢失更新问题的发生的

然而,在实际的开发环境中,我们经常会遇到逻辑缺失的更新。例如:

[En]

However, in a real development environment, we often encounter * logical missing updates * . For example:

1)事务 T1 查询一行数据 r,放入本地内存,并显示给一个用户 User1

2)事务 T2 也查询该行数据,并将取得的数据显示给另一个用户 User2

3)User1 修改了行记录 r 为 v1,更新数据库并提交

4)User2 修改了行记录 r 为 v2,更新数据库并提交

显然,最终这行记录的值是 v2,User1 的更新操作被 User2 覆盖掉了,丢失了他的修改。

三分钟图解事务隔离级别,看一遍就懂

可能还是云里雾里,我来举个 更现实点的例子吧,一个部门共同查看一个在线文档,员工 A 发现自己的性别信息有误,于是将其从 “女” 改成了 “男”,就在这时,HR 也发现了员工 A 的部门信息有误,于是将其从 “测试” 改成了 “开发”,然后,员工 A 和 HR 同时点了提交,但是 HR 的网络稍微慢一点,再次刷新,员工 A 就会发现,擦,我的性别怎么还是 “女”?

三分钟图解事务隔离级别,看一遍就懂

脏读 Dirty Read

所谓脏读,就是说 一个事务读到了另外一个事务中的 “脏数据”,脏数据就是指事务未提交的数据

如下图所示,在事务并没有提交的前提下,事务 T1 中的两次 SELECT 操作取得了不同的结果:

三分钟图解事务隔离级别,看一遍就懂

注意,如果想要再现脏读这种情况,需要把隔离级别调整在 Read UnCommitted(读取未提交)。所以事实上脏读这种情况基本不会发生,因为现在大部分数据库的隔离级别都至少设置成 READ COMMITTED

不可重复读 Unrepeatableread

不可重复读取意味着同一数据集在一个事务内被多次读取。在事务结束之前,另一个事务访问相同的数据集并进行一些修改。因此,在第一个事务中的两次读取之间,第一个事务读取的数据可能会因为第二个事务的修改而不同。

[En]

Non-repeatable reading means that the same data set is read multiple times within a transaction. Before the transaction ends, another transaction accesses the same data set and makes some modifications. Therefore, * between the two reads in the first transaction, the data read by the first transaction may be different because of the modification of the second transaction.*

举个例子:事务 T1 读取一行数据 r,T2 将该行数据修改成了 v1。如果 T1 再次读取这行数据,此时读取的结果和第一次读取的结果是不同的

三分钟图解事务隔离级别,看一遍就懂

不可重复读取和脏读取之间的区别在于,脏读取是读取未提交的数据,而不可重复读取是已提交的数据,但它违反了事务一致性的要求。

[En]

The difference between unrepeatable reading and dirty reading is that dirty reading is reading uncommitted data, while unrepeatable reading is committed data, but it violates the requirement of transaction consistency.

幻读 Phantom Read

幻影阅读本质上是一种不可重复的阅读。不同的是,不可重复读取主要针对数据的更新(即事务的两次读取结果不同)。虚读主要针对数据的增加或减少(即事务的两次读取返回的结果数量不同)。

[En]

Phantom reading is essentially a case of unrepeatable reading. the difference is that unrepeatable reading is mainly aimed at the update of data (that is, the results of the two reads of the transaction are different). The phantom reading is mainly aimed at the increase or decrease of data (that is, the number of results returned by the two reads of the transaction is not the same).

举个例子:事务 T1 读取某个范围的数据,事务 T2 在这个范围内插入了一些新的数据,然后 T1 再次读取这个范围的数据, 此时读取的结果比第一次读取的结果返回的记录数要多

三分钟图解事务隔离级别,看一遍就懂

四种事务隔离级别标准

SQL 标准定义了四种越来越严格的事务隔离级别,用来解决我们上述所说的四种事务的并发一致性问题。

1) READ UNCOMMITTED 读取未提交:事务中的修改,即使没有提交,对其它事务也是可见的。

如上所述,数据库本身已经具有防止丢失更新的能力,也就是说,即使是最低隔离级别也可以防止丢失更新。所以:

[En]

As mentioned above, the database itself already has the ability to prevent lost updates, that is, even the lowest isolation level can prevent lost updates. So:

  • 这个隔离级别可以阻止 丢失更新

2) READ COMMITTED 读取已提交:一个事务只能读取已经提交的事务所做的修改。换句话说,一个事务所做的修改在提交之前对其它事务是不可见的。

  • 这个隔离级别可以阻止 丢失更新 + 脏读

3) REPEATABLE READ 可重复读(InnoDB 存储引擎默认的隔离级别):保证在同一个事务中多次读取同一数据的结果是一样的

  • 这个隔离级别可以阻止 丢失更新 + 脏读 + 不可重复读

4) SERIALIZABL 可串行化:强制事务串行执行(需要使用锁机制来实现),这样多个事务互不干扰,不会出现并发一致性问题。

  • 这个隔离级别可以阻止 丢失更新 + 脏读 + 不可重复读 + 幻读

三分钟图解事务隔离级别,看一遍就懂

您可以看到,四个隔离级别可以防止越来越多的并发一致性问题,但这并不意味着隔离级别越高越好,因为事务隔离级别越高,数据库的性能成本就越大。

[En]

You can see that more and more concurrency consistency problems can be prevented by the four isolation levels, but it does not mean that the higher the isolation level, the better, because the higher the transaction isolation level, the greater the performance cost of the database.

另外,多提一嘴,InnoDB 存储引擎在 REPEATABLE READ 事务隔离级别下,使用 Next-Key Lock 锁的算法避免了幻读的产生。也就是说,InnoDB 存储引擎在其默认的 REPEATABLE READ 事务隔离级别下就已经能完全保证事务的隔离性要求了,即达到了 SQL 标准的 SERIALIZABLE 隔离级别。

🎉 关注公众号 | 飞天小牛肉,即时获取更新

  • 博主东南大学硕士在读,携程 Java 后台开发暑期实习生,利用课余时间运营一个公众号『 飞天小牛肉 』;,2020/12/29 日开通,专注分享计算机基础(数据结构 + 算法 + 计算机网络 + 数据库 + 操作系统 + Linux)、Java 技术栈等相关原创技术好文。关注公众号第一时间获取文章更新, 后台回复 300 即可免费获取极客大学出品的 Java 面试 300 题
  • 并推荐个人维护的开源教程类项目: CS-Wiki(Gitee 推荐项目,现已累计 1.8k+ star), 致力打造完善的后端知识体系,在技术的路上少走弯路,欢迎各位小伙伴前来交流学习 ~ 😊
  • 如果各位小伙伴春招秋招没有拿得出手的项目的话,可以参考我写的一个项目「开源社区系统 Echo」Gitee 官方推荐项目,目前已累计 900+ star,基于 SpringBoot + MyBatis + MySQL + Redis + Kafka + Elasticsearch + Spring Security + … 并提供详细的开发文档和配套教程。公众号后台回复 Echo 可以获取配套教程,目前尚在更新中。

Original: https://www.cnblogs.com/cswiki/p/15384346.html
Author: 飞天小牛肉
Title: 三分钟图解事务隔离级别,看一遍就懂

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/508070/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • nginx反向代理proxy_pass url后加/和不加/的区别

    在nginx中配置proxy_pass反向代理时,当在后面的url加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理走;如果没有/,则会把匹配的路…

    数据库 2023年6月6日
    0118
  • 普通 Docker 与 Kubernetes 对比

    Docker提供基本容器管理 API 和容器镜像文件格式Kubernetes 管理运行容器的(物理或虚拟)主机群集,如果 Docker 是 OCP 的”内核&#8221…

    数据库 2023年6月14日
    066
  • Eureka详解系列(四)–Eureka Client部分的源码和配置

    按照原定的计划,我将分三个部分来分析 Eureka 的源码: 今天,我们来研究第二部分的源码。 我的思路是这样子的:先明确 Eureka Client 拥有哪些功能,然后从源码角度…

    数据库 2023年6月6日
    083
  • 如何制作验证码

    推导步骤1:在img标签的src属性里放上验证码的请求路径 补充1.img的src属&amp…

    数据库 2023年6月14日
    079
  • jmeter-跨线程组全局变量

    需求:两个线程组(A线程组与B线程组)👉A线程组的变量信息被B线程组引用。 操作: 1. A线程组使用登录接口获取token、通过Json提取器获取到登录token, 然后添加&#…

    数据库 2023年6月14日
    085
  • SQL的约束

    概念:约束是作用于表中的字段以限制表中数据存储的规则 [En] concept: constraints are rules that act on fields in a tab…

    数据库 2023年5月24日
    095
  • 一,Flink快速上手

    1.依赖配置 1.1 pom文件 8 8 1.13.0 1.8 2.12 1.7.30 org.apache.flink flink-java ${flink.version} o…

    数据库 2023年6月6日
    092
  • 数据结构知识详解 第一章 绪论

    知识框架 1. 数据结构的基本概念 1.1 基本概念和术语 1.1.1 数据 定义:是信息的载体,是描述客观事实属性的数、字符及所有能输入到计算机中并被计算机程序识别和处理的符号的…

    数据库 2023年6月11日
    074
  • 【Java代码之美】 — Java11新特性解读

    1.背景 美国时间 09 月 25 日,Oralce 正式发布了 Java 11,这是据 Java 8 以后支持的首个长期版本。非常值得大家的关注,可以通过下面的地址进行下载: h…

    数据库 2023年6月6日
    092
  • DM变更表空间存放路径

    1、变更前置条件 (1)、数据库服务器提供dmdba用户权限 (2)、目标路径有足够的空间可以使用 (3)、数据库可以重启 2、变更实施过程 2.1、变更前备份变更表空间目录需要对…

    数据库 2023年6月11日
    0160
  • Python–异常

    1 # -*- coding:utf-8 -*- 2 name = ‘tj’ 3 try: 4 int(name) 5 except (IndexError,KeyError) a…

    数据库 2023年6月9日
    066
  • Java中的SPI原理浅谈

    在面向对象的程序设计中,模块之间交互采用接口编程,通常情况下调用方不需要知道被调用方的内部实现细节,因为一旦涉及到了具体实现,如果需要换一种实现就需要修改代码,这违反了程序设计的&…

    数据库 2023年6月14日
    067
  • 生成随机数的若干种方法

    背景: 创建账户时我们需要配置初始随机密码,使用手机号注册时需要随机验证码,抽奖活动需要随机点名,俄罗斯方块游戏需要随机出形状。这些案例都在说明一个问题,随机数据很重要!而在 Sh…

    数据库 2023年6月14日
    062
  • [springmvc]ajax异步请求数据详细简单

    10.Ajax异步请求 Ajax即 Asynchronous Javascript And XML(异步JavaScript和XML在 2005年被Jesse James Garr…

    数据库 2023年6月16日
    073
  • 16-ArrayList和LinkedList的区别

    1.1、作用 ArrayList和LinkedList都是实现了List接口的容器类,用于存储一系列的对象引用。它们可以对元素的增删改查进行操作 对于ArrayList,它在集合的…

    数据库 2023年6月16日
    076
  • MySQL45讲之备库并行复制策略

    前言 本文主要介绍 MySQL 备库的并行复制策略。 为什么备库需要并行复制 如果主数据库有大量的更新操作,因为主数据库可以并发写入,而从数据库只能在单个线程中执行,那么从数据库的…

    数据库 2023年5月24日
    077
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球