【MySQL】深度理解事务的隔离性:全面讲解事务的四种隔离级别

**前言:**上节内容我们主要说了如果没有设置保存点, 也可以回滚,但是只能回滚到事务的开始。直接使用rollback的前提是事务还没有提交。并且如果一个事务被提交了,就不可以回退。同时我们也可以使用savepoint设置回滚点。 可以自己选择想要回滚到的位置。同时最后我们也提到了,InnoDB支持事务, 但是MyISAM不支持事务。 这节就将更深入的使用事务。 看一下事物的特性——隔离性。下面友友们开始学习吧!

ps:本节内容建议友友们能够知道最基本的事务操作在观看哦。

目录

事务的隔离性

如何理解隔离性

隔离级别

?隔离试验示例

如何查, 设置mysql的隔离界别

读未提交

?编辑

读提交?

?可重复读

串行化


事务的隔离性

要理解隔离性, 我们就要知道什么叫做隔离性, 什么叫做隔离级别, 为什么会有这么多隔离级别。

如何理解隔离性

首先我们要知道, mysql在启动后, 一定会被多个客户端并发的访问。另外,我们可以向mysql同时发送多个事务, 对于我们上层来说,这些事务一定有执行前, 执行中, 执行后。一旦执行中出现问题, 就会发生回滚。所以单个事务,对用户表现出来的特性, 就是原子性。

而且, 多个事务执行的时候, 可能会互相影响。比如同时访问一张表, 同时修改一张表。所以, 在数据库当中,为了保证事务之间尽量互不干扰,就有了一个重要的特性——隔离性。

数据库中,允许事务收到不同程度的干扰, 这个就叫做隔离级别。

那么我们用一个故事来谈一谈数据的隔离性。

如果两个人都在同时访问数据库。 这两个人都开启了事务。 但是一个人想要update, 一个人想要select。 那么请问是update先跑呢, 还是select先跑呢? ——有人会说让update先跑, 因为我们要确定我们看到的是最新的。 ——这种说法是错误的。

为什么错误。 就可以这么来看——就比如一个小孩出生, 假如这个小孩是00后。 他的父母是70后, 80后。 那么这个小孩是不是需要关注他的父母从出生到生下他这段时间里面他的父母做过什么 一般情况下, 是不需要的。 另外, 也比如一个革命战士, 就比如一百年前, 几十年前的革命战士。 他们在他们的那个年代努力奋斗。但是他们看不看的到如今的中国是什么样子的呢? 答案是也看不到。 ——每一个人, 都只是需要看到自己从出生到死亡的这一段时间内的事情。 其他时间段的时间, 这些人不需要关心。 而这些, 其实就是隔离性。 就是说我们不用获取信息总是获取最新的, 也不能获取信息总是获取最旧的。 我们只需要获取自己这个时间段内的就行。

所以, 对于update和select谁先跑, 应该是取决于两个谁先来的, 谁先来的谁就先跑。虽然事务有执行中,事务有可能交叉, 但是事务是一个原子整体。 对于事务来说, 谁先到来, 谁就先执行。但是对于先到来的事务不一定先退出。可能先到的执行的很慢, 后到来的执行的很快。那么后到来的先执行完, 先到来的后执行完。而且可能在我们到来的期间, 另一个事务把数据更新了。 然后我们此时select应不应该看到最新的数据呢? ——答案是不应该!!!因为我们要保证隔离性。

另外,隔离是运行中的事务,进行相互隔离。 在事务运行中, "不会"出现互相干扰,此时就有了隔离性。根据影响程度的不同,就有了隔离级别。

隔离级别

  • 读未提交:事务1所做的任何修改, 不需提交事务2也能立即看到。
  • 读提交:事务1所做的任何修改, 只有当提交后事务2才能立即看到。
  • 可重复读:事务1无论做任何修改以及提交。 只有当事务2也结束后,再启事务才能看到。隔离级别较高, 也是mysql默认的隔离级别。
  • 串行化:最高的隔离界别所有的CURD操作, 必须按照到来的顺序一个一个执行, 一个执行完才能下一个。

隔离试验示例

如何查, 设置mysql的隔离界别

要查看隔离界别, 首先我们要知道什么是会话隔离界别, 什么是全局隔离级别。 会话隔离界别就是session.tx_isolation。 也就是只影响这一次登录。 而全局隔离级别global.tx_isolation也影响后续的登录。

select @@global.transaction_isolation;--查看全局隔级别

select @@transaction_isolation; --查看会话(当前)全局隔级别

select @@session.transaction_isolation; --查看会话隔离界别

然后设置隔离界别

set [session | global] transaction isolation level {read uncommitte | read committed | repeatable read | serializable}

上面的方括号里面的session和global二选一, 设置系统还是会话。 然后花括号里面的四个选择一个。 读未提交, 读提交, 可重复读, 串行化。

现在试验一下串行化

设置当前会话串行化:

set session transaction isolation level serializable;

但是新起会话不收到影响:

再设置回来:

set session transaction isolation level read uncommitted;

如果全局隔离级别和会话隔离级别不同, 就会默认使用会话隔离级别。

读未提交

我们现在来读未提交。

先启动两个事务:

然后右边查看一下表中的数据:

然后在左边插入数据张三:

之后再从右边查看, 就能看到数据已经查看到了。

我们左边还没提交呢, 右边就能看到。 这就叫什么, 这就叫做读未提交!一个事务在执行中,读到另一个事务的更新但是还没有commit的数据, 这种情况叫做脏读。——这是一种不合理的现象。

rollback回滚也能看到数据又恢复了:

读提交

先将事务的隔离级别改为读提交:

两边启动事务:

先查看一下表中的数据:

然后我们插入数据张三:

然后右边查一下数据, 会发现看不到表数据的更新:

但是我们左边查的话就能看到:

然后我们左边提交commit:

右边再查, 就会看到数据修改了:

这种一旦提交就能看到的就叫做读提交。 读提交好像解决了脏读的问题。 但是又出现了另一个问题:就是我们左边在提交前和提交后, 我们右边select查到的数据结果是不一样的。 也就是说我们右边一直select, 结果某一次select的时候, 数据突然变了。 ——这种现象, 就叫做不可重复读。

那么, 不可重复读是问题吗?

——首先, 我们提交了,就让另一个人看到, 不应该吗? 其实是应该的。 但是不应该让另一个人在运行期间看到, 应该是让另一个人结束后, 再起事务的时候看到

就比如我们的一个表, 有员工ID, 有员工名字, 有员工薪资。如果路人A想要涨工资, 就和老板去谈。 谈妥了,老板就告诉路人B修改一下数据库中的路人A的薪资。 这个时候呢, 路人C正在查数据库中的人们的薪资, 根据薪资来归类。 所以呢,这个时候路人C通过筛选, 先查工资(1000-2000)的人,里面有路人A。 然后呢, 路人B就对路人A的薪资进行修改, 修改成了2500。 然后路人C查的有点慢, 他敲了半天, 终于查出了(2000-3000)的工资的人。 然后一看, 里面也有路人A。 那么这就出现了问题, 这个路人A出现了两次。 那么这个路人C对于路人A到底该怎么分类, 就出现问题了。

所以, 不可重复读有问题吗? 答案是有问题。

可重复读

先设置可重复读:

启动我们的事务:

然后查看我们的数据:

然后我们进行插入,之后右边查看, 会发现, 右边没有数据更新:

然后我们左边直接提交了, 右边也看不见:

这种即便commit, 其他事务也看不到, 就叫做可重复读。

然后重启事务, 就能看到了:

对于可重复读, 有的数据库因为insert的插入有些特殊, insert不能可重复读。所以就形成了幻读现象, 也就是好像出现了幻觉一样。 mysql是解决了这个问题的。

串行化

设置隔离级别:

然后启动事务, 先启动左边事务, 再启动右边事务:

然后左侧查找, 能将数据查出来:

然后右边我们也查, 也能查出来:

然后我们右边删除一下数据张三, 我们会发现, 右边的事务卡在这里了:

然后我们左边的事务commit一下,右边的事务就启动了。

然后我们重启左边事务, 又在右边删除数据田七。 会发现右边不阻塞了。上面这种现象就是串行化的现象, 一开始左边事务先启动, 默认他先执行。 然后右边事务即便修改, 也会阻塞在那里。 然后我们左边事务提交了,再启动。它的顺序相当于在右边事务的后面了。 右边事务就不会被阻塞了。

所以我们发现一个问题, 就是如果我们的客户端里面是查的话, 就直接执行了。但是如果是增删改操作, 就会判断是不是该这个客户端执行,如果不是,就将sql放到等待队列里。前面的事务结束了, 这些sql才能一个一个的执行。

通过上面的例子我们就能看出来, 隔离级别越严苛,安全性就越高。 但是数据库的并发度就越低。所以就要在其中找到一个平衡点。根据实际需求, 用户就可以使用不同的隔离方案。决定在用户, 不在于数据库, 所以mysql提供了四种隔离级别!!!

——————以上就是本节全部内容哦, 如果对友友们有帮助的话可以关注博主, 方便学习更多知识哦!!!

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

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

相关文章

项目实战 —— HTTP服务器设计与实现

目录 一,项目介绍 二,背景知识补充 2.1 http特点 2.2 URI,URL,URN 2.3 http请求方法 三,前置功能实现 3.1 日志编写 3.2 封装相关套接字 3.3 http请求结构设计 3.4 http响应结构设计 3.5 http服务器主体逻辑…

GitHub Copilot:智能助手觉醒

GitHub Copilot: The agent awakens - The GitHub Blog github copilot 官方文档刚刚宣布支持 agent 模式! 这一模式和之前的 chat 方式不同,类似于 cursor 可以根据需求直接运行、调试和修改代码 这一模式在 preview 版本可以使用,并且需…

网络安全威胁框架与入侵分析模型概述

引言 “网络安全攻防的本质是人与人之间的对抗,每一次入侵背后都有一个实体(个人或组织)”。这一经典观点概括了网络攻防的深层本质。无论是APT(高级持续性威胁)攻击、零日漏洞利用,还是简单的钓鱼攻击&am…

深入浅出谈VR(虚拟现实、VR镜头)

1、VR是什么鬼? 近两年VR这次词火遍网上网下,到底什么是VR?VR是“Virtual Reality”,中文名字是虚拟现实,是指采用计算机技术为核心的现代高科技手段生成一种虚拟环境,用户借助特殊的输入/输出设备&#x…

postman免登录版本,实测可用(解决一直卡在登录界面无法进入的问题)

一、背景 2025今年开工后,打开postman,一直提示需要登录,但是一直卡在登录界面,好几个人的postman都是这样的情况,不知道是什么原因。 折腾几小时无果,网上下载了各种版本都试了,最新的版本也…

Unity中Spine骨骼动画完全指南:从API详解到避坑实战

Unity中Spine骨骼动画完全指南:从API详解到避坑实战 一、为什么要选择Spine? Spine作为专业的2D骨骼动画工具,相比传统帧动画可节省90%资源量。在Unity中的典型应用场景包括: 角色换装系统(通过插槽替换部件&#xf…

HTTP异步Client源码解析

我们知道Netty作为高性能通信框架,优点在于内部封装了管道的连接通信等操作,用户只需要调用封装好的接口,便可以很便捷的进行高并发通信。类似,在Http请求时,我们通过调用HttpClient,内部使用java NIO技术&…

Golang:Go 1.23 版本新特性介绍

流行的编程语言Go已经发布了1.23版本,带来了许多改进、优化和新特性。在Go 1.22发布六个月后,这次更新增强了工具链、运行时和库,同时保持了向后兼容性。 Go 1.23 的新增特性主要包括语言特性、工具链改进、标准库更新等方面,以下…

无界构建微前端?NO!NO!NO!多系统融合思路!

文章目录 微前端理解1、微前端概念2、微前端特性3、微前端方案a、iframeb、qiankun --> 使用比较复杂 --> 自己写对vite的插件c、micro-app --> 京东开发 --> 对vite支持更拉跨d、EMP 方案--> 必须使用 webpack5 --> 很多人感觉不是微前端 --> 去中心化方…

SQL Server 数据库迁移到 MySQL 的完整指南

文章目录 引言一、迁移前的准备工作1.1 确定迁移范围1.2 评估兼容性1.3 备份数据 二、迁移工具的选择2.1 使用 MySQL Workbench2.2 使用第三方工具2.3 手动迁移 三、迁移步骤3.1 导出 SQL Server 数据库结构3.2 转换数据类型和语法3.3 导入 MySQL 数据库3.4 迁移数据3.5 迁移存…

RabbitMQ深度探索:死信队列

死信队列产生背景: RabbitMQ 死信队列俗称 备胎队列:消息中间件因为某种原因拒收该消息后,可以转移到私信队列中存放,死信队列也可以有交换机和路由 key 等 生产死信队列的原因: 消息投递到 MQ 存放,消息已…

蓝桥算法基础2

位运算 按位与,x&1x%2.因为1不论和几位二进制与,都只有最后一位为1,前面都是0,那么&前面也都为0,只有最后一位,若为1那么2的0次方为1,该数一定为奇数,与取余结果同&#xff…

B站自研的第二代视频连麦系统(上)

导读 本系列文章将从客户端、服务器以及音视频编码优化三个层面,介绍如何基于WebRTC构建视频连麦系统。希望通过这一系列的讲解,帮助开发者更全面地了解 WebRTC 的核心技术与实践应用。 背景 在文章《B站在实时音视频技术领域的探索与实践》中&#xff…

redis之AOF持久化过程

流程图 在redis.conf文件中配置appendonly为yes则开启aof持久化机制 #开启aof持久化,默认关闭为no appendonly no也可以在命令行开启 aof刷盘策略 #每个写操作都会同步刷盘。 appendfsync always #执行命令后先放入aof缓冲区,每秒钟将缓冲区数据刷盘…

力扣.623. 在二叉树中增加一行(链式结构的插入操作)

Problem: 623. 在二叉树中增加一行 文章目录 题目描述思路复杂度Code 题目描述 思路 1.首先要说明,对于数据结构无非两大类结构:顺序结构、链式结构,而二叉树实质上就可以等效看作为一个二叉链表,而对于链表插入一个节点的操作是应…

【GoLang】切片的面试知识点

nil切片 和 空切片 nil切片是只声明但未初始化,没有分配底层数组的内存空间, 空切片是初始化了的,有分配数组内存,只是数组内没有元素。 二者都可以正常扩容、遍历。不会报错。 append 如何添加切片 append 可以增加切片&…

利用 IMU 估计人体关节轴向和位置 —— 论文推导

Title: 利用 IMU 估计人体关节轴向和位置 —— “Joint axis and position estimation from inertial measurement data by exploiting kinematic constraints” —— 论文推导 文章目录 I. 论文回顾II. 铰接关节的约束1. 铰接关节约束的原理2. 铰接关节约束的梯度3. 铰接关节约…

JVM图文入门

往期推荐 【已解决】redisCache注解失效,没写cacheConfig_com.howbuy.cachemanagement.client.redisclient#incr-CSDN博客 【已解决】OSS配置问题_keyuewenhua.oss-cn-beijing.aliyuncs-CSDN博客 【排坑】云服务器docker部署前后端分离项目域名解析OSS-CSDN博客 微服…

利用ETL工具进行数据挖掘

ETL的基本概念 数据抽取(Extraction):从不同源头系统中获取所需数据的步骤。比如从mysql中拿取数据就是一种简单的抽取动作,从API接口拿取数据也是。 数据转换(Transformation):清洗、整合和转…

MySQL数据库(五)索引

一 索引概述 1 介绍:MySQL索引是一种有序数据结构,它能够高效帮助数据库系统快速定位到表中的特定记录,从而显著提高查询效率。索引可以被看作是书的目录,通过它可以迅速找到所需的信息而不需要逐页翻阅整本书。 2 优缺点 二 索…