MySQL篇:事务

1.四大特性

首先,事务的四大特性:ACID(原子性,一致性,隔离性,持久性)

在InnoDB引擎中,是怎么来保证这四个特性的呢?

  • 持久性是通过 redo log (重做日志)来保证的;
  • 原子性是通过 undo log(回滚日志) 来保证的;
  • 隔离性是通过 MVCC(多版本并发控制) 或锁机制来保证的;
  • 一致性则是通过持久性+原子性+隔离性来保证;

然后的话,我们这次重点讲一下事务的隔离性。

2.并发事务会带来哪些问题?

        MySQL是允许多个客户端连接的,这样就会导致MySQL同时处理多个事务的情况。

那么,就会出现以下三个问题:脏读,不可重复读,幻读

脏读:A事务读到了B事务还未提交且修改过的数据。

         比如A第一次读某人卡里的余额为100,然后A把这个余额修改为200但是不提交事务,此时B正好也来读取余额得到200,然后A把这个修改进行了回滚(100),那么B读到的就是脏数据了。

不可重复读:A事务前后两次读的数据不一致

        比如A第一次读某人卡里余额100,然后B来把这个余额进行了修改为200并且提交了事务,那么A再一次读取卡里余额,就变成200了,前后两次读取的数据不一致。

幻读:A事务多次查询某个条件的记录数量,前后两次查询得到的记录数量不一致。

        比如A第一次读取余额大于100的用户有5个,然后此时B来插入了一条数据(余额为150)并提交了事务,然后A第二次读取余额大于100的用户变成了6个,前后两次读取的记录数量不一致。

3.事务的隔离级别

3.1.四种隔离级别

那么针对上面的三个问题,SQL标准提出了四种隔离级别来规避这些现象,分别是:

  • 读未提交(read uncommitted),指一个事务还没提交时,它做的变更就能被其他事务看到;
  • 读提交(read committed),RC指一个事务提交之后,它做的变更才能被其他事务看到;
  • 可重复读(repeatable read),RR指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,MySQL InnoDB 引擎的默认隔离级别;
  • 串行化(serializable );会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行;

 对于上面四种隔离级别,每个级别还存在的问题有如下:

        所以,要解决脏读现象,就要升级到「读已提交」以上的隔离级别;要解决不可重复读现象,就要升级到「可重复读」的隔离级别,要解决幻读现象不建议将隔离级别升级到「串行化」。

        这是因为,MySQL的InnoDB引擎在可重复读的级别下,很大程度的规避了幻读现象(不是完全规避),我们在后面重点讲可重复读这一块。

3.3.可重复读(RR)是如何工作的?

        可重复读级别是在启动事务之后,第一次读取数据时,生成一个Read View,以后的本事务中每次普通查询语句都会依据这个Read View来获取数据。

3.4 读已提交(RC)是如何工作的?

        读已提交级别是在启动事务后,每次读取数据时,都会生成一个新的Read View。

4.可重复读怎么很大程度解决幻读现象?

4.1针对普通select语句(快照读)

        是通过MVCC的方式解决了幻读,因为RR级别下,开始事务后,在执行第一个查询语句,就会创建一个Read View,后续的查询语句,都是在这个Read View的基础上来得到数据的。所以即使中途有其他事务插入了新记录,那么也是查不出来这个新数据的。

 4.2针对select..for update语句(当前读)

       MySQL 里除了普通查询是快照读,其他都是当前读,比如 update、insert、delete,这些语句执行前都会查询最新版本的数据,然后再做进一步的操作。

那么如果在当前读的情况下没有加锁,那就会出现幻读现象,如下:

        所以,InnoDB引擎为了解决 “在可重复读隔离级别下使用当前读” 而导致的幻读问题,就引出了间隙锁。

        间隙锁,顾名思义是在一个范围之间加锁,那么在这个范围之内,其他事务就无法进行增删改操作了。

        假设,表中有一个范围 id 为(3,5)间隙锁,那么其他事务就无法插入 id = 4 这条记录了,这样就有效的防止幻读现象的发生。

        

然后我们举个具体的例子:

        事务A执行了这条sql语句之后,就会对表中的记录加上id范围为(2,+∞] 的next-key lock,

(这个next-key lock是间隙锁+记录锁的组合,锁的是左开右闭的区间。) 然后事务B在执行sql语句的时候,被事务A加的next-key lock给阻塞了,那么事务B就会生成一个意向锁,等待事务A提交之后,再进行插入操作,这样就避免了因为B事务插入新数据而导致A事务出现幻读的情况。

5.可重复读级别下幻读被完全解决了吗?

        通过上面两种情况所做的处理,可以说是很大程度上避免了幻读现象,但是还没有完全解决幻读现象。

例如:

5.1.可重复读级别下幻读情况1

  1. A开启事务,并且查询id=5的数据,不存在。
  2. B开启事务,插入一条id=5的数据,并提交事务。
  3. A直接进行update操作,修改id=5的数据,此时如果再次执行查询id=5的操作,那么就会查询到id=5的数据了!

        这种情况就是在A开启事务后,通过普通的sql语句生成了一个Read View,之后事务B向表中插入新数据并提交。紧接着事务A对id=5的数据进行update操作,我们前面提到要进行update操作,就必须获取到当前读,那么这样的话,就会导致事务A再次查询的时候,查询的就是最新的数据,就会出现幻读了。

5.2.可重复读级别下幻读情况2

  1. A开启事务,然后执行:select * from t_test where id > 100 (快照读)得到3条记录。
  2. B开启事务,往里面插入了一个 id=200 的记录并提交事务。
  3. A继续执行:select * from t_test where id > 100 for update (当前读)得到4条记录。

        这种情况就属于,A开启事务后没有马上执行select...for update操作,导致第一次读取数据时没有加next-key lock,从而导致B事务插入了新数据。

6.总结

  1. 事务的四大特性:ACID(原子性,一致性,隔离性,持久性)
  2. 持久性<-RedoLog , 一致性<-UndoLog ,隔离性<-MVCC || 锁 ,持久性<-前三个一起保证
  3. 并发事务带来的危害:脏读,可重复读,幻读
  4. 四种隔离级别:读未提交,读已提交(RC),可重复读(RR),串行化
  5. 可重复读解决可重复读隔离级别(默认隔离级),提出的避免幻读的方案:
  • 针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读。(生成快照读,后续的读都是基于第一次的快照读来获取数据)
  • 针对当前读(select ... for update 等语句),是通过 next-key lock(记录锁+间隙锁)方式解决了幻读。

备注:图片摘抄自小林coding,如有侵权,联系删除。

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

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

相关文章

Andriod Stdio新建Kotlin的Jetpack Compose简单项目

1.选择 No Activity 2.选择kotlin 4.右键选择 在目录MyApplication下 New->Compose->Empty Project 出现下面的画面 Finish 完成

聊聊常见的分布式ID解决方案

highlight: xcode theme: vuepress 为什么要使用分布式ID&#xff1f; 随着 Web 开发技术的不断发展&#xff0c;单体的系统逐步走向分布式系统。在分布式系统中&#xff0c;使用分布式 ID(Distributed IDs)主要是为了在没有单点故障的情况下生成唯一标识符。这些唯一标识符在很…

【Linux】进程间通信——命名管道和共享内存

目录 命名管道&#xff08;named pipe&#xff09; 命令行中使用 代码中使用 共享内存&#xff08;shared memory&#xff09; shmget ipcs命令 shmctl shmat/shmdt 简单通信 命名管道&#xff08;named pipe&#xff09; 之前我们说了匿名管道&#xff0c;但是匿名管道…

为什么要使用加密软件?

一、保护数据安全&#xff1a;加密软件通过复杂的加密算法对敏感数据进行加密处理&#xff0c;使得未经授权的人员即使获取了加密数据&#xff0c;也无法轻易解密和获取其中的内容。这极大地提高了数据在存储、传输和使用过程中的安全性。 二、遵守法律法规&#xff1a;在许多国…

无人机图像目标检测

本仓库是人工智能课程的课程作业仓库&#xff0c;主要是完成无人机图像目标检测的任务&#xff0c;我们对visdrone数据集进行了处理&#xff0c;在yolo和ssd两种框架下进行了训练和测试&#xff0c;并编写demo用于实时的无人机图像目标检测。 requirements依赖&#xff1a; ss…

ubuntu虚拟机安装ssh时报错 正在等待缓存锁

问题&#xff1a; 连接vm ubuntu虚拟机安装ssh时报错 正在等待缓存锁。 sudo apt install openssh-server 处理办法 sudo rm /var/lib/dpkg/lock-frontend sudo rm /var/cache/apt/archives/lock sudo rm /var/lib/dpkg/lock

K8S ingress 初体验 - ingress-ngnix 的安装与使用

准备环境 先把 google 的vm 跑起来… gatemanMoreFine-S500:~/projects/coding/k8s-s/service-case/cloud-user$ kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane,master 124d v1.23.6 k8s-no…

python数据可视化(5)——绘制饼图

课程学习来源&#xff1a;b站up&#xff1a;【蚂蚁学python】 【课程链接&#xff1a;【【数据可视化】Python数据图表可视化入门到实战】】 【课程资料链接&#xff1a;【链接】】 Python绘制饼图分析北京天气 饼图&#xff0c;是一个划分为几个扇形的圆形统计图表&#xff…

爬虫-requests和Selenium

1、了解requests的功能 1.1 使用post和get发送请求 HTTP中常见发送网络请求的方式有两种&#xff0c;GET和POST。GET是从指定的资源请求数据&#xff0c;POST是向指定的资源提交要被处理的数据。 GET的用法&#xff1a; import requestsr requests.get("https://www.…

Milvus 核心设计(5)--- scalar indexwork mechanism

目录 背景 Scalar index 简介 属性过滤 扫描数据段 相似性搜索 返回结果 举例说明 1. 属性过滤 2. 扫描数据段 3. 相似性搜索 实际应用中的考虑 Scalar Index 方式 Auto indexing Inverted indexing 背景 继续Milvus的很细设计&#xff0c;前面主要阐述了Milvu…

Swift网络爬虫与数据可视化的结合 (1)

前言 在当今数字化时代&#xff0c;数据的重要性不言而喻。Swift&#xff0c;作为一种现代的编程语言&#xff0c;以其高性能、易用性和安全性&#xff0c;成为了开发iOS和macOS应用的首选。本文将探讨如何使用Swift来开发一个网络爬虫&#xff0c;以及如何将爬取的数据进行可…

图像边缘检测中Sobel算子的原理,并附OpenCV和Matlab的示例代码

Sobel算子是一种用于图像边缘检测的离散微分算子。它结合了图像的平滑处理和微分计算&#xff0c;旨在强调图像中强度变化显著的区域&#xff0c;即边缘。Sobel算子在图像处理中被广泛使用&#xff0c;特别是在计算机视觉和图像分析领域。 Sobel算子的原理 Sobel算子主要用于计…

【数学建模与优化】:解析与实践

目录 数学建模概述 1. 什么是数学模型 2. 数学模型的分类 2.1 按应用领域分类 2.2 按建模方法分类 2.3 按是否考虑随机因素分类 2.4 按变量的连续性分类 2.5 按对对象内部规律了解程度分类 2.6 按变量的基本关系分类 2.7 按是否考虑时间变化分类 3. 数学规划及优化模…

【车载开发系列】GIT教程---如何下载代码库

【车载开发系列】GIT教程—如何下载代码库 【车载开发系列】GIT教程---如何下载代码库 【车载开发系列】GIT教程---如何下载代码库一. 设置用户名和邮箱二. 生成SSH三. 登录远程github仓库配置四. Git中的ssh协议介绍五. 什么是GitLab六. GitLab与GitHub区别1&#xff09;用途和…

Python 获取今天(当天)、昨天(前一天)、前天(昨天的前一天)的开始时间、结束时间

描述&#xff1a;我这里是封装成DatetimeHelper工具类来调用 1.今天(当天)开始时间、结束时间 from datetime import datetime, timedeltaclass DatetimeHelper:# 获取今天(当天)的开始时间、结束时间(datetime类型)staticmethoddef getTodayStartEnd():# 获取当前的日期now …

nginx生成自签名SSL证书配置HTTPS

一、安装nginx nginx必须有"--with-http_ssl_module"模块 查看nginx安装的模块&#xff1a; rootecs-7398:/usr/local/nginx# cd /usr/local/nginx/ rootecs-7398:/usr/local/nginx# ./sbin/nginx -V nginx version: nginx/1.20.2 built by gcc 9.4.0 (Ubuntu 9.4.0…

HarmonyOS 屏幕适配设计

1. armonyOS 屏幕适配设计 1.1. 像素单位 &#xff08;1&#xff09;px (Pixels)   px代表屏幕上的像素点&#xff0c;是手机屏幕分辨率的单位&#xff0c;即屏幕物理像素单位。 &#xff08;2&#xff09;vp (Viewport Percentage)   vp是视口百分比单位&#xff0c;基于…

如何在excel表中实现单元格满足条件时整行变色?

可以试试使用条件格式&#xff1a; 一、条件格式 所谓“自动变色”就要使用条件格式。 先简单模拟数据如下&#xff0c; 按 B列数字为偶数 为条件&#xff0c;整行标记为蓝色背景色。 可以这样设置&#xff1a; 先选中1:10行数据&#xff0c;在这里要确定一下名称栏里显示…

元器件基础学习笔记——磁珠

一、磁珠的作用及构造 1.1 磁珠的作用 磁珠是一种用于抑制高频噪声的被动电子组件&#xff0c;通常由铁氧体材料制成&#xff0c;这种材料具有高电阻率和高磁导率&#xff0c;使其能够在高频下有效地将干扰信号以热能的形式消耗掉。在电路设计中&#xff0c;磁珠被广泛用于信号…

SQL Server设置定时作业调度Schedule

文章目录 SQL Server代理 SQL Server代理 SQL Server提供了一种称为SQL Server代理的功能&#xff0c;可以用来设置定时作业。以下是在SQL Server中设置定时作业的步骤&#xff1a; 打开SQL Server Management Studio&#xff08;SSMS&#xff09;。 连接到要设置定时作业的数…