SQL事务与隔离

news2024/9/20 8:04:36

事务

事务的定义

事务是完成一个任务的多条语句,这些语句中,只要有一条语句失败,那么整个事务就会失败,即使之前的语句已经执行完毕也会被撤回

举个例子:

我去银行给王哥转钱,这个转钱呢分两个步骤,第一步先把我的钱拿出来,第二步把钱给王哥,那万一刚把我钱拿出来但是没到王哥账户里面呢银行爆炸了,我钱直接凭空消失,这是不合理的,所以我们使用事务,把两个操作放在一个事务当中,往王哥账户转钱的操作没完成,那么我的钱就会退回

事务的性质

事务有四大特性,各取首字母得到 ACID(“酸的”):

  1. Atomicity 原子性,即整体性,不可拆分行(unbreakable),所有语句必须都执行成功事务才算完成,否则只要有语句执行失败,已执行的语句也会被复原
  2. Consistency 一致性,指的是通过事务我们的数据库将永远保持一致性状态,比如不会出现没有完整订单项目的订单
  3. Isolation 隔离性,指事务间是相互隔离互不影响的,尤其是需要访问相同数据时。具体而言,如果多个事务要修改相同数据,该数据会被锁定,每次只能被一个事务有权修改,其它事务必须等这个事务执行结束后才能进行
  4. Durability 持久性,指的是一旦事务执行完毕,这种修改就是永久的,任何停电或系统死机都不会影响这种数据修改

创建事务 

START TRANSACTION;



COMMIT;

在这两行命令之间放我们的业务代码即可

如果我们写着写着突然发现写错了 那可以直接用ROLLBACK代替COMMIT

autocommit

我们执行的SELECT、INSERT、UPDATE 或 DELETE 语句其实都被MYSQL自动包装成了一个事务然后自动提交

SHOW VARIABLES LIKE 'autocommit';

 我们可以看到这个参数是打开的

并发问题

 Lost Updates 丢失更新

 A操作的更新还没结束,此时B的更新操作读取到的还是未更新的值 所以等B实际更新完成后 就把A的操作覆盖了

Dirty Reads 脏读

事务A将某顾客的积分从10分增加为20分,但在提交前就被事务B读取了,事务B按照这个尚未提交的顾客积分确定了折扣数额,可之后事务A被退回了,所以该顾客的积分其实仍然是10分,因此事务B等于是读取了一个数据库中从未提交的数据并以此做决定,这被称作为脏读

Non-repeating Reads 不可重复读取 (或 Inconsistent Read 不一致读取)

事务A的语句里需要读取两次某顾客的积分数据,读取第一次时是10分,此时事务B把该积分更新为0分并提交,然后事务A第二次读取积分为0分,这就发生了不可重复读取 或 不一致读取

保持数据一致性,以事务A在开始执行时的数据初始状态为依据来做决定,如果这是我们想要的话,就要增加事务A的隔离等级,让它在执行过程中看不见其它事务的数据更改(即便是提交过的),SQL有个标准隔离等级叫 Repeatable Read 可重复读取,可以保证读取的数据是可重复和一致的,无论过程中其它事务对数据做了何种更改,读取到的都是数据的初始状态

Phantom Reads 幻读

幻读错误的理解:说幻读是事务A 执行两次 select 操作得到不同的数据集,即 select 1 得到10条记录,select 2 得到11条记录。这其实并不是幻读,这是不可重复读的一种,只会在 R-U R-C 级别下出现,而在 mysql 默认的 RR 隔离级别是不会出现的。

幻读,并不是说事务中多次读取获取的结果集不同,幻读更重要的是某次的 select 操作得到的结果集所表征的数据状态无法支撑后续的业务操作。更为具体一些:select 记录不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,如同产生了幻觉

隔离级别

Read Uncommitted读取未提交

最低等级的隔离级别解决不了任何问题,就是说这个事务还没提交呢,其他的事务就可以读取它的数据了,或者就直接理解成完全没有隔离

Read Committed 读取已提交

只能读取已提交的数据,这防止了Dirty Reads 脏读

Repeatable Read 可重复读取

不同的读取会返回相同的结果,即便数据在这期间被更改和提交,以事务开始读取到的数据为准

Serializable 序列化

可以防止以上所有问题,这一级别还能防止幻读,如果有其他事务修改了可能影响结果的数据 我们的事务必须等待它完成,但这很明显会给服务器增加负担,因为管理等待的事务需要消耗额外的储存和CPU资源

关于这些有一个很有意思的总结,就是我们认为读取已提交是锁住了读行为(不能读未提交的数据) 所以解决了脏读问题

可重复提交锁住了行 所以解决了行修改造成的并发问题(丢失更新 不可重复读)

序列化锁住了表 所以解决了插入,删除对整张表的问题(幻读)

更低的隔离级别更容易并发,会有更多用户能在相同时间接触到相同数据,但也因此会有更多的并发问题,另一方面因为用以隔离的锁定更少,性能会更高

相反,更高的隔离等级限制了并发并减少了并发问题,但代价是性能和可扩展性的降低,因为我们需要更多的锁定和资源

MySQL的默认等级是 Repeatable Read 可重复读取,它可以防止除幻读外的所有并发问题并且比序列化更快,多数情况下应该保持这个默认等级。

如果对于某个特定的事务,防止幻读至关重要,可以改为 Serializable 序列化

对于某些对数据一致性要求不高的批量报告或者对于数据很少更新的情况,同时又想获得更好性能时,可考虑前两种等级

总的来说,一般保持默认隔离等级,只在特别需要时才做改变

设置隔离级别的方法:

SET [SESSION]/[GLOBAL] TRANSACTION ISOLATION LEVEL SERIALIZABLE

SESSION 就是设置本次会话(链接)之后所有事务的隔离等级,加上 GLOBAL 就是设置之后所有对话的所有事务的隔离等级

LEVEL后面写对应隔离

死锁

事务里的增删改语句都会锁定相关行(,如果两个同时在进行的事务分别锁定了对方下一步要使用的行,就会发生死锁,死锁不能完全避免但有一些方法能减少其发生的可能性

 事务1执行到第二个修改的时候 发现该行事务2锁定了

事务2执行到第二个修改的时候 发现该行事务1锁定了(只有事务整体执行完才会释放锁)

规避死锁的方法:

  1. 注意语句顺序:如果检测到两个事务总是发生死锁,检查它们的代码,这些事务可能是储存过程的一部分,看一下事务里的语句顺序,如果这些事务以相反的顺序更新记录,就很可能出现死锁,为了减少死锁,我们在更新多条记录时可以遵循相同的顺序
  2. 尽量让你的事务小一些,持续时间短一些,这样就不太容易和其他事务相冲突
  3. 如果你的事务要操作非常大的表,运行时间可能会很长,冲突的风险就会很高,看看能不能让这样的事物避开高峰期运行,以避开大量活跃用户

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

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

相关文章

大数据分析案例-基于LightGBM算法构建公司破产预测模型

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

1.网络基础

什么是网络? 信息传递,资源共享 计算机—1946年2月14日—电脑 电流—二进制— 1001—人类语言(抽象语言)—应用程序—编译—编码—应用层 把人类语言转化为二进制—表示层(编码表) 网路层——路由器&#x…

AI 绘画 - 建筑绘图辅助设计之生图

前情提要 2023-06-16 周五 杭州 小雨 小记: 今天下班,回来比较晚,端午节去看老弟,只希望下周不要那么多乱七八糟的事情了,继续AI 绘画,之前上学的时候从来不爱做笔记的,现在或许是老了吧,。 …

C语言复习笔记5

1.函数 #include<stdio.h>void Add(int *p) {(*p); }int main() {int time0;Add(&time);printf("%d\n",time);return 0; }2.二分查找 #include<stdio.h>void Add(int *p) {(*p); }int main() {int time0;Add(&time);printf("%d\n",t…

Linux常用命令——findfs命令

在线Linux命令查询工具 findfs 标签或UUID查找文件系统 补充说明 findfs命令依据卷标&#xff08;Label&#xff09;和UUID查找文件系统所对应的设备文件。findfs命令会搜索整个磁盘&#xff0c;看是否有匹配的标签或者UUID没有&#xff0c;如果有则打印到标注输出上。find…

Spring中的设计模式

目录 1.Spring中使用到的设计模式有&#xff1a; 2.工厂模式 3.单例模式 4.代理模式 5.模板模式 6.适配器模式 1.Spring中使用到的设计模式有&#xff1a; 工厂模式&#xff1a;实现IoC容器 单例模式&#xff1a;将bean设置为单例 代理模式&#xff1a;AOP的底层实现 模板…

聊一聊.NET的网页抓取和编码转换

在本文中&#xff0c;你会了解到两种用于 HTML 解析的类库。另外&#xff0c;我们将讨论关于网页抓取&#xff0c;编码转换和压缩处理的知识&#xff0c;以及如何在 .NET 中实现它们&#xff0c;最后进行优化和改进。 文章目录 1. 背景2. 网页抓取3. 编码转换4. 网页压缩处理5.…

C#,数值计算——哈夫曼编码与数据压缩技术(Huffman Coding and Compression of Data)源代码

1 霍夫曼编码导论 霍夫曼编码是一种基于数据集中符号频率的无损数据压缩形式。它是一种前缀编码方案&#xff0c;这意味着编码的数据不包含任何冗余比特。霍夫曼编码广泛应用于各种应用&#xff0c;如图像和视频压缩、数据传输和数据存储。 2 霍夫曼编码的优点 以下是霍夫曼编…

[LeetCode周赛复盘] 第 326 场周赛20230702

[LeetCode周赛复盘] 第 326 场周赛20230702 一、本周周赛总结6909. 最长奇偶子数组1. 题目描述2. 思路分析3. 代码实现 6916. 和等于目标值的质数对1. 题目描述2. 思路分析3. 代码实现 6911. 不间断子数组1. 题目描述2. 思路分析3. 代码实现 6894. 所有子数组中不平衡数字之和…

【小沐学Unity3d】Unity播放视频(VideoPlayer组件)

文章目录 1、简介2、脚本播放示例3、界面播放示例3.1 2d界面全屏播放3.2 2d界面部分区域播放3.3 3d模型表面播放 结语 1、简介 使用视频播放器组件可将视频文件附加到游戏对象&#xff0c;然后在运行时在游戏对象的纹理上播放。 视频播放器 (Video Player) 组件: 属性功能Sourc…

Java实现OpenAI 模型训练(fine-tune)

本文章介绍如何用java实现OpenAI模型训练&#xff0c;仅供参考 提前准备工作 OpenAI KEY&#xff0c;获取方式可自行百度需要自备VPN 或 使用国外服务器转发需要训练的数据集&#xff0c;文章格式要求为JSONL&#xff0c;格式内容详见下图&#xff08;尽量不要低于500个问答&…

openai

⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;努力输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐所属专栏&#xff1a;人工智能。 目录 1、简介2、如何实现3、api文档 1、简介 OpenAI 提供了一个名为 OpenAI API 的库&#xff0c;用…

npm构建vite项目

基础环境 npm init vitelatest 依次输入项目名称、使用框架、使用语言。 生成的项目 进入目录&#xff0c;安装依赖&#xff0c;启动项目。 cd 0702_demo01npm installnpm run dev

网络安全进阶学习第四课——SSRF服务器请求伪造

文章目录 一、什么是SSRF&#xff1f;二、SSRF成因三、SSRF简析四、PHP存在SSRF的风险函数五、后台源码获取方式六、SSRF危害七、SSRF漏洞挖掘从WEB功能上寻找&#xff0c;从URL关键字中寻找 八、SSRF具体利用ssrf常利用的相关协议PHP伪协议读取文件端口扫描 九、SSRF存在的必要…

架构分层方法指导

在《不过时的经典层架构》里讲了经典的四层架构怎样对易变性做封装。咱们实际项目中&#xff0c;如果没有足够的实践和关键性思考&#xff0c;还是很可能使用名义上科学的分类理论&#xff0c;却在按照功能进行架构分层。今天咱们就通过一些简单的指导来尽量减少这种风险。 四问…

LeetCode 75 —— 70. 爬楼梯

LeetCode 75 —— 70. 爬楼梯 一、题目描述&#xff1a; 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法…

机器学习笔记 - 基于OpenCV和Vantage-point tree构建图像哈希搜索引擎

一、关于图像哈希 上一篇文章中,了解到了图像哈希是使用算法为图像分配唯一哈希值的过程。在深度学习普及之前,一些搜索引擎使用散列技术来索引图像。 言外之意目前的图像搜索引擎主要都是基于深度学习的技术,不过思路都是一样的,我们这里基于OpenCV提供的图像哈希技术构建…

python实现削苹果小游戏

也不用998只有199源码发你。 支付完发我邮箱发你源代码。

RISC-V处理器的设计与实现(三)—— 上板验证(基于野火征途Pro开发板)

文章目录 RISC-V处理器的设计与实现&#xff08;一&#xff09;—— 基本指令集_Patarw_Li的博客-CSDN博客 RISC-V处理器的设计与实现&#xff08;二&#xff09;—— CPU框架设计_Patarw_Li的博客-CSDN博客 RISC-V处理器的设计与实现&#xff08;三&#xff09;—— 上板验…

Gradle安装与配置(8.2)

一、下载地址 https://gradle.org/releases/ https://downloads.gradle.org/distributions/gradle-8.2-bin.zip 解压后放到合适的位置 二、配置环境变量并测试 D:\ProgramFiles\gradle-8.2\bin gradle -v 三、配置镜像 D:\ProgramFiles\gradle-8.2\init.d init.gradle&…