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

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

不过好在锁只会带来四种问题(丢失更新、脏读、不可重复读、幻读),如果可以防止这四种情况的发生,那将不会产生并发异常。为此,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)

大家都在看

  • day01-数据库的安装和使用

    Java数据库的安装和使用 1.数据库的作用 一个问题:淘宝网、京东、微信抖音,都有各自的功能,那么我们退出系统的时候,为什么信息还在? 解决之道-文件,数据库 为了解决上诉问题,…

    数据库 2023年6月11日
    0111
  • Linux 服务管理

    Linux 服务管理 1. 基本介绍 服务的本质就是进程,但是是运行在后台的,通常都会监听某个端口,等待其它程序的请求,比如mysqld,sshd,防火墙等,因此我们又称为守护线程…

    数据库 2023年6月6日
    0106
  • 23种设计模式之观察者模式

    文章目录 概述 观察者模式的优缺点 观察者模式应用场景 观察者模式的结构和实现 * 模式结构 模式实现 总结 ; 概述 观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一…

    数据库 2023年6月6日
    0114
  • 智慧 ~ 引子 ~ 三则故事

    年轻人的故事 从前,有位乡下青年,读了点书,嫌乡村的生活单调,决定要去城里闯世界。临走时,他向村中的村长请教,村长给了他三个字的忠告:”不要怕”。并讲好等他…

    数据库 2023年6月9日
    084
  • ShardingSphere-Proxy 前端协议问题排查方法及案例

    ShardingSphere-Proxy 是 Apache ShardingSphere 的接入端之一,其定位为透明化的数据库代理。ShardingSphere-Proxy 实现了…

    数据库 2023年6月16日
    092
  • Spring中常见的注解

    1.组件注解 @Controller @Service @Repository @Component —标注一个类为Spring容器的Bean @Configratio…

    数据库 2023年6月11日
    091
  • Question08-查询没学过”张三”老师授课的同学的信息

    * SELECT * FROM Student WHERE SID NOT IN ( SELECT DISTINCT Student.SID FROM Student , SC ,…

    数据库 2023年6月16日
    093
  • Java数据结构和算法

    一、数据结构 数据结构是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。 通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同…

    数据库 2023年6月11日
    0111
  • Redis缓存雪崩、缓存穿透、缓存击穿

    缓存雪崩 Redis中的缓存数据是有过期时间的,当在同一时间大量的缓存同时失效时就会造成缓存雪崩。解决方案1、设置Redis中的key永不过期,缺点是会占用很多内存2、使用Redi…

    数据库 2023年6月14日
    0102
  • JDBC

    JDBC 一、JDBC概述 什么是JDBC? JDBC 是使用 Java 语言操作关系型数据库的一套 API。这套 API 是交由不同的数据库厂商实现的。我们利用 JDBC 编写操…

    数据库 2023年6月14日
    0119
  • Git 环境搭建

    安装 Git:官网 👉https://git-scm.com/ GIt基础配置(以下操作均在 git bash 窗口下进行) git config –global user.na…

    数据库 2023年6月6日
    086
  • leetcode 208. Implement Trie (Prefix Tree) 实现 Trie (前缀树) (中等)

    Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼…

    数据库 2023年6月16日
    0106
  • 银河麒麟V10安装MySQL8028

    记一次成功安装MySQL8028到银河麒麟V10,并实现远程访问的方法 工具/原料 数据库下载地址(实验版如图): [En] Download address of the dat…

    数据库 2023年5月24日
    096
  • 滑动窗口

    滑动窗口,记录左边界,通过map避免字符重复。 class Solution { public int lengthOfLongestSubstring(String s) { i…

    数据库 2023年6月11日
    083
  • SQLZOO练习5–join(表的连接)

    game表: idmdatestadiumteam1team2 1001 8 June 2012 National Stadium, Warsaw POL GRE 1002 8 J…

    数据库 2023年6月16日
    092
  • Kmp算法

    算法流程: kmp_search(char[] text,char[] pattern) 构建前缀表 prefix[0]默认&#…

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