数据库之事务隔离级别详解

news2024/11/25 12:42:03

事务隔离级别详解

  • 一、事务的四大特性(ACID)
    • 1. 原子性(atomicity):
    • 2. 一致性(consistency):
    • 3. 隔离性(isolation):
    • 4. 持久性(durability):
  • 二、事务的四种隔离级别
    • 1. 读未提交(Read uncommitted):
      • 1.1 简述
      • 1.2 事例
      • 1.3 分析
    • 2. 读已提交(Read committed):
      • 2.1 简述
      • 2.2 事例
      • 2.3 分析
    • 3. 可重复读(Repeatable read)
      • 3.1 简述
      • 3.2 事例
      • 3.3 分析
      • 3.4 什么时候会出现幻读?
        • 3.4.1 简述
        • 3.4.2 事例
        • 3.4.3 那怎么解决幻读问题?
    • 4. 串行化(Serializable)
    • 5. 小结
  • 三、MySql默认隔离级别
      • 1.版本说明
      • 2. 查询mysql全局事务隔离级别
        • 2.1 查询命令
        • 2.2 默认隔离级别如下
      • 3. 注意事项
  • 四、不同隔离级别演示
    • 演示准备
      • 创建sql语句准备
      • 数据准备
    • 读未提交----->脏读
      • 设置当前会话隔离级别为读未提交
        • 1、a 事务(客户端1) 修改 、未提交
        • 2、b事务(客户端2) 读该数据
        • 3、a事务(客户端1) 回滚
        • 4、b事务(客户端2) 再读该数据 和 2步不一致,脏读
    • 读已提交----->不可重复读
      • 设置当前会话隔离级别为读已提交
        • 1、a事务(客户端1) 修改 、未提交
        • 2、b事务(客户端2) 读该数据
        • 3、a事务(客户端1) 提交
        • 4、b事务(客户端2) 读该数据 , 不可重复读
    • 可重复读----->幻读
      • 设置当前会话隔离级别为可重复读
        • 1、a 事务(客户端1) 修改、未提交
        • 2、b 事务(客户端2) 读该数据
        • 3、a 事务(客户端1) 提交
        • 4、b 事务(客户端2) 读该数据 和之前一样可重复读
    • 串行化
      • 设置当前会话隔离级别为串行化
        • 1、a 事务(客户端1) 读取id = 1的数据
        • 2、b 事务(客户端2) 修改id = 1的数据,直接阻塞住
        • 3、a 事务(客户端1) 提交
        • 4、b 事务(客户端2) 获取行锁更新成功、串行执行
  • 五、MVCC(Multi-Version Concurrency Control)
    • MVCC原理底层就是通过read view 以及undo log来实现
    • 为什么会有MVCC
    • MVCC在哪个隔离级别下才生效
    • InnoDB行数据默认隐藏列
    • ReadView是什么
      • read view 参数解释
        • 1.creator_trx_id: 当前事务id
        • 2.m_ids:所有活跃事务的事务id
        • 3.min_trx_id: m_ids里最小的事务id值
        • 4.max_trx_id: 最大事务id
    • Read View快照的生成时机
      • repeatable read级别
      • read committed级别
      • 版本链比对规则
    • 一句话概括MVCC
    • MVCC比对练习题
      • 在同一个事务里,针对id=1的记录,当前事务ID分别为200,99,38,15,5的行记录能查询到么,是可见的么?
      • 思考题:为啥要把最小的事务id值单独作为一个字段?
  • 六、Mysql解决了幻读么,当前读呢

一、事务的四大特性(ACID)

1. 原子性(atomicity):

事务是一个原子操作,要么全部执行成功,要么全部执行失败。 事务的原子性确保一组逻辑操作,要么全部完成,要么完全不起作用。

2. 一致性(consistency):

执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的。

3. 隔离性(isolation):

事务的隔离性是指在并发执行的多个事务中,每个事务的执行互不影响,每个事务都有自己独立的空间进行操作。事务隔离级别越高,数据冲突的可能性就越小,但并发性能也会受到一定的影响。

4. 持久性(durability):

一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障,应用重启,也不应该对其有任何影响。

二、事务的四种隔离级别

数据库事务的隔离级别有4种,由低到高分别为Read uncommitted 、Read committed 、Repeatable read 、Serializable 。在事务的并发操作中可能会出现脏读,不可重复读,幻读。

1. 读未提交(Read uncommitted):

1.1 简述

一个事务读到了另一个事务还没有提交的数据。

1.2 事例

父亲要给儿子转账。但是转账时父亲不小心按错了数字,按成10万/月,该钱已经打到儿子的账户,但是事务还没有提交,就在这时,儿子去查看自己的储蓄卡,发现转多了9万,以为凭空多了9万非常高兴。但是父亲及时发现了不对,马上回滚差点就提交了的事务,将数字改成1万再提交。

1.3 分析

实际父亲给儿子转的还是1万,但是儿子看到的是10万。儿子看到的是父亲还没提交事务时的数据。这就是脏读。

2. 读已提交(Read committed):

2.1 简述

一个事务要等另一个事务提交后才能读取数据。

2.2 事例

儿子拿着父亲的信用卡去消费(卡里目前有10),当他买单时(父亲事务开启),收费系统事先检测到他的卡里有10万,就在这个时候!!父亲要把钱全部转出充当家用,并提交。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测金额当然要等待父亲转出金额事务提交完)。儿子就会很郁闷,明明卡里是有钱的…

2.3 分析

这就是读已提交,若有事务对数据进行更新操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。但在这个事例中,出现了一个事务范围内两次相同的查询却返回了不同数据,这就是不可重复读。

3. 可重复读(Repeatable read)

3.1 简述

同一事务下,事务在执行期间,多次读取同一数据时,能够保证读取到的数据是一致的。

3.2 事例

儿子拿着信用卡去享受生活(卡里只有10万),当他买单时(事务开启,不允许其他事务的UPDATE修改操作),收费系统事先检测到他的卡里有10万。这个时候父亲不能转出金额了。接下来收费系统就可以扣款了。

3.3 分析

可重复读解决了不可重复读的问题。说到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。

3.4 什么时候会出现幻读?

3.4.1 简述

一个事务读取到了另一个事务新增的数据

3.4.2 事例

儿子某一天去消费,花了8千元,然后他的父亲去查看他今天的消费记录(全表扫描,儿子事务开启),看到确实是花了8千元,就在这个时候,儿子花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当父亲打印儿子的消费记录清单时(儿子事务提交),发现花了1.8万元,似乎出现了幻觉,这就是幻读。

3.4.3 那怎么解决幻读问题?

串行化

4. 串行化(Serializable)

它是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率最低,比较耗费数据库性能,一般不推荐使用。

5. 小结

隔离级别脏读不可重复读幻读
读未提交可能出现可能出现可能出现
读已提交不会出现可能出现可能出现
可重复读不会出现不会出现可能出现
串行化不会出现不会出现不会出现

三、MySql默认隔离级别

1.版本说明

这里是8.0.33

mysql版本说明

2. 查询mysql全局事务隔离级别

2.1 查询命令

select @@global.transaction_isolation;

2.2 默认隔离级别如下

默认隔离级别

3. 注意事项

低版本的查询语句是select @@global.tx_isolation;

四、不同隔离级别演示

演示准备

创建sql语句准备

CREATE TABLE user (
	--自增ID
    id INT NOT NULL AUTO_INCREMENT,
    --姓名
    name VARCHAR(50) NOT NULL,
    --年龄
    age INT NOT NULL,
    --主键
    PRIMARY KEY (id)
);

数据准备

--插入一条记录,id为1,name为'张三',age为20
INSERT INTO user(id, name, age) VALUES (1, '张三', 20);
-- 插入一条记录,id为2,name为'李四',age为30
INSERT INTO user(id, name, age) VALUES (2, '李四', 30);
-- 插入一条记录,id为3,name为'王五',age为25
INSERT INTO user(id, name, age) VALUES (3, '王五', 25);
-- 插入一条记录,id为4,name为'赵六',age为28
INSERT INTO user(id, name, age) VALUES (4, '赵六', 28);

读未提交----->脏读

设置当前会话隔离级别为读未提交

读未提交隔离级别设置

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

1、a 事务(客户端1) 修改 、未提交

在这里插入图片描述

2、b事务(客户端2) 读该数据

在这里插入图片描述

3、a事务(客户端1) 回滚

在这里插入图片描述

4、b事务(客户端2) 再读该数据 和 2步不一致,脏读

在这里插入图片描述

读已提交----->不可重复读

设置当前会话隔离级别为读已提交

在这里插入图片描述

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

1、a事务(客户端1) 修改 、未提交

在这里插入图片描述

2、b事务(客户端2) 读该数据

在这里插入图片描述

3、a事务(客户端1) 提交

在这里插入图片描述

4、b事务(客户端2) 读该数据 , 不可重复读

在这里插入图片描述

可重复读----->幻读

设置当前会话隔离级别为可重复读

在这里插入图片描述

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

1、a 事务(客户端1) 修改、未提交

在这里插入图片描述

2、b 事务(客户端2) 读该数据

在这里插入图片描述

3、a 事务(客户端1) 提交

在这里插入图片描述

4、b 事务(客户端2) 读该数据 和之前一样可重复读

在这里插入图片描述

串行化

设置当前会话隔离级别为串行化

在这里插入图片描述

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

1、a 事务(客户端1) 读取id = 1的数据

在这里插入图片描述

2、b 事务(客户端2) 修改id = 1的数据,直接阻塞住

在这里插入图片描述

3、a 事务(客户端1) 提交

在这里插入图片描述

4、b 事务(客户端2) 获取行锁更新成功、串行执行

在这里插入图片描述

五、MVCC(Multi-Version Concurrency Control)

MVCC原理底层就是通过read view 以及undo log来实现

为什么会有MVCC

频繁加锁会导致数据库性能低下,引入了MVCC多版本控制来实现读写不阻塞,提高数据库性能,在多版本并发控制中,为了保证数据操作在多线程过程中,保证事务隔离的机制,降低锁竞争的压力,保证较高的并发量。在每开启一个事务时,会生成一个事务的版本号,被操作的数据会生成一条新的数据行(临时),但是在提交前对其他事务是不可见的,对于数据的更新(包括增删改)操作成功,会将这个版本号更新到数据的行中,事务提交成功,将新的版本号更新到此数据行中,这样保证了每个事务操作的数据,都是互不影响的,也不存在锁的问题。

MVCC在哪个隔离级别下才生效

MVCC只在 READ COMMITTED 和 REPEATABLE READ 两个隔离级别下工作。其他两个隔离级别和MVCC不兼容,因为 READ UNCOMMITTED 总是读取最新的数据行,而不是符合当前事务版本的数据行。而 SERIALIZABLE 则会对所有读取的行都加锁。

InnoDB行数据默认隐藏列

InnoDB在每行数据都增加三个隐藏字段:一个唯一行号,一个记录创建的版本号,一个记录回滚的版本号。

ReadView是什么

在我们平时执行一个事务的时候,就会生成一个ReadView,ReadView的组成结构大致如下:
READVIEW

read view 参数解释

1.creator_trx_id: 当前事务id

没什么可解释,就是当前事务ID

2.m_ids:所有活跃事务的事务id

当前所有未提交的事务id构成的集合

3.min_trx_id: m_ids里最小的事务id值

当前所有未提交的事务id构成的集合里的最小的哪个事务id

4.max_trx_id: 最大事务id

下一个即将创建的事务id

Read View快照的生成时机

repeatable read级别

语句级快照

read committed级别

事务级的快照

版本链比对规则

  1. 如果被访问版本的trx_id属性值与rv中的creator_trx_id值相同 可见
  2. 如果被访问版本的trx_id属性值小于rv中的min_trx_id值 可见
  3. 如果被访问版本的trx_id属性值大于或等于rv中的max_trx_id值 不可见
  4. 如果被访问版本的trx_id属性值在rv的min_trx_id和max_trx_id之间
    4.1 trx_id在m_ids中 不可见
    4.2 trx_id不在m_ids中 可见

一句话概括MVCC

MVCC机制的实现就是通过read-view机制与undo版本链比对机制,使得不同的事务会根据数据版本链对比规则读取同一条数据在版本链上的不同版本数据。

MVCC比对练习题

mvcc

在同一个事务里,针对id=1的记录,当前事务ID分别为200,99,38,15,5的行记录能查询到么,是可见的么?

200不可见、99可见、38可见、15不可见、5可见

思考题:为啥要把最小的事务id值单独作为一个字段?

时间复杂度,难道要从所有未提交的集合中去找么,依次遍历

六、Mysql解决了幻读么,当前读呢

在InnoDB引擎下的的repeatable read (可重复复读)隔离级别下,快照读MVCC影响下,已经解决了幻读的问题(因为它是读历史版本的数据),而如果是当前读(指的是 select * from table for update),则需要配合间隙锁来解决幻读的问题。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WSL怎么使用本机进行代理联网

文章目录 WSL怎么使用本机代理进行联网问题来源设置v2rayN设置wsl总结参考 WSL怎么使用本机代理进行联网 问题来源 使用WSL克隆github的代码网速很慢,无响应,导致项目无法下载,真的愁人。就想到为WSL设置xx上网,是否就会好很多。…

Photoshop如何使用文字之实例演示?

文章目录 0.引言1.给图像素材添加透明水印2.创建路径文字3.创建每日一签海报4.给图像添加复杂水印5.制作个人简历模板 0.引言 因科研等多场景需要进行绘图处理,笔者对PS进行了学习,本文通过《Photoshop2021入门教程》及其配套素材结合网上相关资料进行学…

React | React组件化开发

✨ 个人主页:CoderHing 🖥️ React .js专栏:React .js React组件化开发 🙋‍♂️ 个人简介:一个不甘平庸的平凡人🍬 💫 系列专栏:吊打面试官系列 16天学会Vue 11天学会React Node…

不良条件视觉感知专栏(一)任务前言

前言 随着深度学习的流行,CNN的强大特征学习能力给计算机视觉领域带来了巨大的提升。2D/3D目标检测、语义分割是常见的视觉感知任务,本专栏我们将围绕着它们展开阐述。 本教程禁止转载。同时,本教程来自知识星球【CV技术指南】更多技术教程&…

Photoshop如何使用图像调色之实例演示?

文章目录 0.引言1.将一张偏冷调的图像调整成暖调2.将图像调整成不同季节色彩倾向3.变换花朵的颜色4.创建人像轮廓风景5.修饰蓝天白云6.调换花草颜色 0.引言 因科研等多场景需要进行绘图处理,笔者对PS进行了学习,本文通过《Photoshop2021入门教程》及其配…

【经典论文解读】YOLACT 实例分割(YOLOv5、YOLOv8实例分割的基础)

前言 YOLACT是经典的单阶段、实时、实例分割方法,在YOLOv5和YOLOv8中的实例分割,也是基于 YOLACT实现的,有必要理解一下它的模型结构和设计思路。 论文:YOLACT: Real-time Instance Segmentation 开源地址:https://gi…

01-Shiro550漏洞流程

1. 漏洞原理 Apache Shiro框架提供了记住密码的功能(RememberMe),用户登录成功后会生成经过加密并编码的cookie。在服务端对rememberMe的cookie值,先base64解码然后AES解密再反序列化,就导致了反序列化RCE漏洞。 那么…

hadoop伪分布式搭建教程

官方参数文档 Apache Hadoop 3.3.5 – HDFS Users Guide Hadoop是一个分布式存储和计算框架,由以下几个组件组成: 1. Hadoop Distributed File System (HDFS):Hadoop分布式文件系统,用于存储大量数据,并提供高可靠性和…

Spring源码:动态代理的增强顺序(AOP与事务的先后)

前文: 《Spring AOP源码:开启注解读取》 《Spring AOP源码2:查找增强器》 《Spring AOP源码3:实现代理》 《Spring事务源码:创建代理类》 《Spring事务源码:事务创建》 《Spring事务源码:…

(05)基础强化:字符串拘留池,格式化,StringBuilder,垃圾回收,弱引用

一、复习 1.什么是接口?说说你对接口的理解。 (提示:概念、语法、应用场景,与抽象类的区别。说出最特别的) 接口是一种规范、标准,一种抽象的概念,所以本身无法实现&#…

Redis基础——Java客户端Jedis

2.1.Jedis客户端 Jedis的官网地址&#xff1a; https://github.com/redis/jedis 2.1.1.快速入门 我们先来个快速入门&#xff1a; 1&#xff09;引入依赖&#xff1a; <!--jedis--> <dependency><groupId>redis.clients</groupId><artifactId&…

山东专升本计算机第九章-信息安全

信息安全 计算机病毒 考点 4病毒的定义与特点 定义 • 一组人为设计的程序满足一定条件即被激活 特点 • 可执行性 • 破坏性 • 占用系统资源 • 破坏或删除程序或数据文件 • 传染性 • 潜伏性 • 隐蔽性 • 针对性 • 宏病毒只感染docx • 衍生性 • 抗反病毒软…

102-Linux_I/O复用方法之poll

文章目录 1.poll系统调用的作用2.poll的原型3.poll支持的事件类型4.poll实现TCP服务器(1)服务器端代码:(2)客户端代码:(3)运行结果截图: 1.poll系统调用的作用 poll 系统调用和 select 类似&#xff0c;也是在指定时间内轮询一定数量的文件描述符&#xff0c;以测试其中是否有…

docker容器原理及简单且详细的使用

docker原理简单介绍 docker是一种虚拟化容器技术。 虚拟化&#xff1a;早期为了节约成本和学习只有在宿主机中基于 kvm&#xff08;基于内核的虚拟机&#xff09;等技术虚拟出来完整的操作系统&#xff0c;而这个完整的操作系统会大量的占用宿主机的硬件资源&#xff0c;当创建…

spring的安装 -- IEDA-创建 Java 工程的jar包教程--以及spring5的核心组件

目录 Spring Spring 基本介绍 Spring5 下载 进入 Spring5 进入 Spring5 的 github 进入 Spring5 的 github下拉 Access to Binaries, 进入 Spring -----拷贝下载地址&#xff0c;打开--- -----选择 5.3.8, 点击进入, 即可下载- 在线文档: 离 线 文 档 : 离 线 API: …

【刷题之路Ⅱ】LeetCode 92. 反转链表 II

【刷题之路Ⅱ】LeetCode 92. 反转链表 II 一、题目描述二、解题1、方法1——穿针引线法1.1、思路分析1.2、代码实现 2、方法2——针对进阶的头插法2.1、思路分析2.2、代码实现 一、题目描述 原题连接&#xff1a; 92. 反转链表 II 题目描述&#xff1a; 给你单链表的头指针 he…

基于全过程通道相关像素值顺序的彩色图像可逆数据隐藏

文献学习&#xff1a; 基于全过程通道相关像素值顺序的彩色图像可逆数据隐藏 原文题目&#xff1a; Reversible data hiding for color images based on pixel value order of overall process channel. 发表期刊&#xff1a; Signal Processing&#xff08;中科院二区&#xf…

AOP(面向切面编程)

3、AOP 3.1、场景模拟 3.1.1、声明接口 声明计算器接口Calculator&#xff0c;包含加减乘除的抽象方法 public interface Calculator {int add(int i, int j);int sub(int i, int j);int mul(int i, int j);int div(int i, int j); }3.1.2、创建实现类 public class Calcul…

osgGA::CameraManipulator类computeHomePosition函数分析

osgGA::CameraManipulator类computeHomePosition函数代码如下&#xff1a; void CameraManipulator::computeHomePosition(const osg::Camera *camera, bool useBoundingBox) {if (getNode()){osg::BoundingSphere boundingSphere;OSG_INFO<<" CameraManipulator::…

继续细说文件

先来了解几个函数&#xff1a; fopen&#xff0c;这个函数有2个参数分别为&#xff08;字符串也就是要记得打引号&#xff09;路径&#xff0c;和&#xff08;字符串&#xff09;操作模式&#xff0c;返回值为FILE类型的指针&#xff0c;也就是一个指向文件信息的结构的指针&a…