数据库的隔离机制---对MySQL 默认隔离级别的理解

参考:

脏读、幻读和不可重复读_脏读 ​​​​​​

全网最详细MVCC讲解,一篇看懂 - 知乎全网最详细MVCC讲解,一篇看懂 - 知乎

面试官:MySQL 的默认隔离级别是什么?可以解决幻读问题吗?

目录

一、脏读、幻读、不可重复读

二、数据库的隔离机制

(一)数据库通过锁机制解决并发访问的问题

(二)SQL 标准定义了四个隔离级别

        1.READ-UNCOMMITTED(读取未提交) 

2.READ-COMMITTED(读取已提交) 

        3.REPEATABLE-READ(可重复读)

        4.SERIALIZABLE(可串行化)

三、REPEATABLE-READ(可重复读)解决幻读问题

(一)MVCC机制 


一、脏读、幻读、不可重复读

脏读(读取未提交数据)
        A事务先读取B事务尚未提交的数据,此时如果B事务这些尚未提交的数据发生错误并执行回滚操作,把数据恢复成原来的,而事务A却什么都不知道,那么A事务读取到的数据就是脏数据。

幻读(前后多次读取,数据总量不一致)

        事务A在执行读取操作,需要两次统计数据的总量,前一次查询数据总量后,此时事务B执行了新增数据的操作并提交后,这个时候事务A读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白无故的多了几条数据,成为幻读。

        幻读指的是两次查询(可能对象是n条记录)获取的结果集不同(因为另一个事务新增或者删除记录行)幻读侧重的是数据的条数发生了变化,原本不存在的数据存在了或原本存在的数据不存在了。

不可重复读(前后多次读取,数据内容不一致)
        事务A在执行读取操作,由整个事务A比较大,前后读取同一条数据需要经历很长的时间 。而在事务A第一次读取数据,比如此时读取了小明的年龄为20岁,事务B执行修改操作,将小明的年龄更改为30岁,此时事务A第二次读取到小明的年龄时,发现其年龄是30岁,和之前的数据不一样了,也就是数据不重复了,系统不可以读取到重复的数据,成为不可重复读。

        

        不可重复度主要是对一条数据查询,同样的条件,你读取过的数据,再次读取出来发现值不一样了进行查询。不可重复读侧重数据的内容发生了变化,原本存在的数据的内容发生了改变。

二、数据库的隔离机制

(一)数据库通过锁机制解决并发访问的问题

  • 根据锁定对象不同:分为行级锁和表级锁
  • 根据并发事务锁定的关系上看:分为共享锁定和独占锁定:共享锁定会防止独占锁定但允许其他的共享锁定。而独占锁定既防止共享锁定也防止其他独占锁定。为了更改数据,数据库必须在进行更改的行上施加行独占锁定,insert、update、delete和selsct for update语句都会隐式采用必要的行锁定。

但是直接使用锁机制管理是很复杂的,基于锁机制,数据库给用户提供了不同的事务隔离级别,只要设置了事务隔离级别,数据库就会分析事务中的sql语句然后自动选择合适的锁
 

(二)SQL 标准定义了四个隔离级别

        1.READ-UNCOMMITTED(读取未提交) 

  • 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。

  • 一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。这样就避免了更新丢失,却可能出现脏读。也就是说事务B读取到了事务A未提交的数据。


    2.READ-COMMITTED(读取已提交) 

  • 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

  • 读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行


        3.REPEATABLE-READ(可重复读)

                                ---MySQL InnoDB 存储引擎的默认支持的隔离级别

  • 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

  • 在一个事务内,多次读同一数据。在A事务还没有结束时,B事务也访问该同一数据。那么,在A事务中的两次读数据之间,即使B事务对数据进行修改,A事务两次读到的的数据是一样的。这样就发生了在一个事务内两次读到的数据是一样的,因此称为是可重复读。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。这样避免了不可重复读取和脏读,但是有时可能出现幻象读


        4.SERIALIZABLE(可串行化)

  • 最高的隔离级别,完全服从 ACID(事务四大特性) 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

  • 要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。

                 ​​​​ 事务的隔离级别和数据库并发性是成反比的,隔离级别越高,并发性越低。

三、REPEATABLE-READ(可重复读)解决幻读问题

标准的 SQL 隔离级别定义里,REPEATABLE-READ(可重复读)是不可以防止幻读的。

但是!InnoDB 实现的 REPEATABLE-READ 隔离级别其实是可以解决幻读问题发生的,主要有下面两种情况:

  • 快照读:由 MVCC 机制来保证不出现幻读。

  • 当前读:使用 Next-Key Lock 进行加锁来保证不出现幻读,Next-Key Lock 是行锁(Record Lock)和间隙锁(Gap Lock)的结合,行锁只能锁住已经存在的行,为了避免插入新行,需要依赖间隙锁。

因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是 READ-COMMITTED ,但是InnoDB 存储引擎默认使用 REPEATABLE-READ 并不会有任何性能损失。

          

(一)MVCC机制 

全称 Multi-Version Concurrency Control,即多版本并发控制

  • 主要目的是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁(降低死锁风险)。
  • 多版本指的是数据库中同时存在多个版本的数据,并不是整个数据库的多个版本,而是某一条记录的多个版本同时存在。

1.当前读和快照读

当前读

在MySQL中,当前读是一种读取数据的操作方式,它可以直接读取最新的数据版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。MySQL提供了两种实现当前读的机制:

  • 一致性读(Consistent Read):
    • 默认隔离级别(可重复读)下,MySQL使用一致性读来实现当前读。
    • 在事务开始时,MySQL会创建一个一致性视图(Consistent View),该视图反映了事务开始时刻数据库的快照
    • 在事务执行期间,无论其他事务对数据进行了何种修改,事务始终使用一致性视图来读取数据。
    • 这样可以保证在同一个事务内多次查询返回的结果是一致的,从而实现了当前读。
  • 锁定读(Locking Read):
    • 锁定读是一种特殊情况下的当前读方式,在某些场景下使用。
    • 当使用锁定读时,MySQL会在执行读取操作前获取共享锁或排他锁,以确保数据的一致性。
    • 共享锁(Shared Lock)允许多个事务同时读取同一数据,而排他锁(Exclusive Lock)则阻止其他事务读取或写入该数据。
    • 锁定读适用于需要严格控制并发访问的场景,但由于加锁带来的性能开销较大,建议仅在必要时使用。

当前读实际上是一种加锁的操作,是悲观锁的实现。


快照读

快照读是在读取数据时读取一个一致性视图中的数据,MySQL使用 MVCC 机制来支持快照读。

  • 每个事务在开始时会创建一个一致性视图(Consistent View),该视图反映了事务开始时刻数据库的快照。这个一致性视图会记录当前事务开始时已经提交的数据版本。
  • 当执行查询操作时,MySQL会根据事务的一致性视图来决定可见的数据版本。只有那些在事务开始之前已经提交的数据版本才是可见的,未提交的数据或在事务开始后修改的数据则对当前事务不可见。
  • 所以,快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本。

注意:快照读的前提是隔离级别不是串行级别,在串行级别下,事务之间完全串行执行,快照读会退化为当前读

MVCC主要就是为了实现读-写冲突不加锁,而这个读指的就是快照读,是乐观锁的实现


2.一致性视图

只针对 RC (读已提交)和 RR(可重复读)级别,不针对 RU级别 和 Serializable级别。

主要原因是:

  • Read Uncommitted(RU)隔离级别: 在 RU 隔离级别下,事务可以读取其他事务尚未提交的数据,即脏读。这意味着不需要通过 一致性视图 来限制访问范围,事务可以自由地读取其他事务的未提交数据。由于没有对可见性进行严格控制,因此不需要创建或使用 一致性视图
  • Serializable(串行化)隔离级别: 在 Serializable 隔离级别下,事务具有最高的隔离性,确保每次读取都能看到一致的快照。为了实现这种隔离级别,MySQL使用锁机制来保证事务之间的串行执行。由于事务按顺序执行,并且不允许并发操作,所以不需要使用 一致性视图 进行可见性判断。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/473471.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UNI-APP小程序答题功能开发(左右滑动,判断,填空,问答,答题卡,纠错,做题倒计时等)

原博&#xff1a;uni-app小程序答题功能开发(左右滑动,判断,填空,问答,答题卡,纠错,做题倒计时等)_uniapp答题模板-CSDN博客 标签&#xff1a; 小程序 uni-app 模板链接:答题模板 html部分 这里没啥好说的,就是根据不同的状态显示不同的内容 <template><view>…

SpringBoot多环境配置的实现

前言 开发过程中必然使用到的多环境案例&#xff0c;通过简单的案例分析多环境配置的实现过程。 一、案例 1.1主配置文件 spring:profiles:active: prod server:port: 80801.2多环境配置文件 开发环境 blog:domain: http://localhost:8080测试环境 blog:domain: https:/…

另外一种缓冲式图片组件的用法

文章目录 1. 概念介绍2. 使用方法2.1 基本用法2.2 缓冲原理3. 示例代码4. 内容总结我们在上一章回中介绍了"FadeInImage组件"相关的内容,本章回中将介绍CachedNetworkImage组件.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章回中介绍的CachedNetwo…

Linux下多线程

在Linux下的底层里并没有多线程这个概念&#xff0c;取而代之的是轻量级进程的概念。应为在Llinu下内核下并没有TCB,而只有PCB。 线程是什么 在⼀个程序⾥的⼀个执⾏路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“⼀个进程内部 的控制序…

Win10/11 安装使用 Neo4j Community Edition

如果你下载的是 Neo4j Community Edition 的压缩包&#xff0c;意味着你需要手动解压并配置 Neo4j。以下是详细的使用步骤&#xff1a; 0. 下载压缩包 访问Neo4j官网&#xff0c;找到 Community Edition 版本并选择 4.x 或者 5.x 下载&#xff1a;https://neo4j.com/deployme…

PCB+SMT线上报价系统+PCB生产ERP系统自动化拼板模块升级

PCB生产ERP系统的智能拼版技术&#xff0c;是基于PCB前端报价系统获取到的用户或市场人员已录入系统的板子尺寸及set参数等&#xff0c;按照最优原则或利用率最大化原则自动进行计算并输出拼版样式图和板材利用率&#xff0c;提高工程人员效率&#xff0c;减少板材的浪费。覆铜…

Excel根据条件动态索引单元格范围

假如我是一个老板&#xff0c;下面有数不胜数的员工&#xff0c;我要检查他们每周的工作产出&#xff0c;列一个排行榜&#xff0c;提高员工积极性&#xff0c;毕竟多劳多得嘛。 每天去手动统计&#xff0c;未免显得不太聪明&#xff0c;我们可以利用公式来解决这个问题。 我们…

SpringBoot配置相关的内容

依赖Starter和Parent 查依赖坐标网站&#xff1a;Maven Repository: Search/Browse/Explorehttps://mvnrepository.com/ 设置配置文件 配置文件相关的配置 yml多个数据的书写 配置文件的读取

机器学习-37-对ML的思考之机器学习发展的三个阶段和驱动AI发展三驾马车的由来

文章目录 1 引言2 机器学习发展的三个阶段2.1 萌芽期(20世纪50年代)2.1.1 达特茅斯会议(人工智能诞生)2.1.2 机器学习名称的由来2.2 知识期(20世纪80年代)2.2.1 知识瓶颈问题2.2.2 机器学习顶级会议ICML2.2.3 Machine Learning创刊2.2.4 神经网络规则抽取2.3 算法期(20世纪90年…

使用win32com将ppt(x)文件转换为pdf文件

本文来记录下如何使用win32com将ppt(x)文件转换为pdf文件 文章目录 win32com概述win32com优缺点代码实例本文小结 win32com概述 Pywin32 是一个用于与 Microsoft Windows 操作系统交互的 Python 扩展模块&#xff0c;它提供了对多个 Windows API 的访问&#xff0c;包括对 Mic…

鸿蒙实战:页面跳转

文章目录 1. 实战概述2. 实现步骤2.1 创建项目2.2 准备图片素材2.3 编写首页代码2.4 创建第二个页面 3. 测试效果4. 实战总结 1. 实战概述 实战概述&#xff1a;本实战通过ArkUI框架&#xff0c;在鸿蒙系统上开发了一个简单的两页面应用。首页显示问候语和“下一页”按钮&…

uniapp微信小程序接入airkiss插件进行WIFI配网

本文可参考uniapp小程序插件 一.申请插件 微信公众平台设置页链接&#xff1a;微信公众平台 登录您的小程序微信公众平台&#xff0c;进入设置页&#xff0c;在第三方设置->插件管理->添加插件中申请AiThinkerAirkissforWXMini插件&#xff0c;申请的插件appId为【wx6…

django解决跨域问题

django解决跨域问题 第一步 查看自己的 django 依赖里面有没有 django-cors-headers 包 直接 cmd pin list第二步如果没有 在自己的 pycharm 里面安装 django-cors-headers 包 pip install django-cors-headers第三步检查是否安装成功 查看自己的 django-cors-headers 安…

【51单片机】LCD1602液晶显示屏

学习使用的开发板&#xff1a;STC89C52RC/LE52RC 编程软件&#xff1a;Keil5 烧录软件&#xff1a;stc-isp 开发板实图&#xff1a; 文章目录 LCD1602存储结构时序结构 编码 —— 显示字符、数字 LCD1602 LCD1602&#xff08;Liquid Crystal Display&#xff09;液晶显示屏是…

【C++派生类新增对象的初始化顺序】单继承下派生类新增成员对象的初始化顺序

单继承下派生类新增成员对象的初始化顺序 &#xff08;1&#xff09;【意识】派生类新增成员对象也要初始化&#xff0c;千万别忘&#xff01; &#xff08;2&#xff09;派生类构造函数执行顺序 ①调用基类构造函数 ②对派生类的新增成员对象初始化[调用顺序为类中声明顺序] ③…

红外遥控信号解码

红外遥控信号解码 之前就已经做过红外遥控的解码了&#xff0c;但是一直没有做记录&#xff0c;最近的项目又使用到了红外遥控&#xff0c;索性就把他捡起来记录一下&#xff0c;对于信号的解码&#xff0c;我一般的习惯都是先用逻辑分析仪抓取一下信号波形&#xff0c;然后对…

基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络

一、介绍 垃圾识别分类系统。本系统采用Python作为主要编程语言&#xff0c;通过收集了5种常见的垃圾数据集&#xff08;‘塑料’, ‘玻璃’, ‘纸张’, ‘纸板’, ‘金属’&#xff09;&#xff0c;然后基于TensorFlow搭建卷积神经网络算法模型&#xff0c;通过对图像数据集进…

stdin文件流指针

stdin文件流指针&#xff08;FILE *&#xff09;&#xff0c;用于表示标准输入流。它通常与键盘进行交互&#xff0c;也可以通过重定向将其他输入源作为标准输入。

GPU分布式通信技术-PCle、NVLink、NVSwitch深度解析

GPU分布式通信技术-PCle、NVLink、NVSwitch 大模型时代已到来&#xff0c;成为AI核心驱动力。然而&#xff0c;训练大模型却面临巨大挑战&#xff1a;庞大的GPU资源需求和漫长的学习过程。 要实现跨多个 GPU 的模型训练&#xff0c;需要使用分布式通信和 NVLink。此外&#xf…

调用门提权

在我写的2.保护模式&#xff0b;段探测这篇文章中&#xff0c;我们提到了S位对于段描述符的控制&#xff0c;之前我们已经介绍了代码段和数据段&#xff0c;现在我们来把目光转到系统段 在这么多中结构里面&#xff0c;我们今天要介绍的就是编号为12的&#xff0c;32位调用门 结…