【MySQL】并发执行事务可能存在的问题, 事务的四种隔离级别

news/2025/2/25 4:00:01

文章目录

  • 前言
  • 一、并发执行事务可能存在的问题
  • 二、MySQL 的四种隔离级别
    • 1, READ UNCOMMITTED 读未提交
    • 2, READ COMMITTED 读已提交
    • 3, REPEATABLE READ 可重复读 (MySQL 的默认事务隔离级别)
    • 4, SERIALIZABLE 串行化
  • 总结


前言

各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你:
📕 JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等
📗 Java数据结构: 顺序表, 链表, 堆, 二叉树, 二叉搜索树, 哈希表等
📘 JavaEE初阶: 多线程, 网络编程, TCP/IP协议, HTTP协议, Tomcat, Servlet, Linux, JVM等(正在持续更新)

在这里插入图片描述

面试中问到 MySQL , 一定会问的就是并发执行事务可能存在的问题, 事务的四种隔离级别相关的问题, 所以这些知识非常重要 ! !


提示:是正在努力进步的小菜鸟一只,如有大佬发现文章欠佳之处欢迎批评指点~ 废话不多说,直接上干货!

一、并发执行事务可能存在的问题

接下来先用通俗的语言, 解释一下这些 “专业术语” 的意思, 然后再 “专业性” 的总结

1, 脏读问题

场景 :

  • 比如我在宿舍库库敲代码, 我的室友要抄我的代码, 我一边写他一边看

  • 趁他不看的时候, 我把代码修改了

  • 过了一会他又来看了, 看到了我的代码已经修改了, 或者是删了

当 事务A 对某个数据修改的过程中, 事务A 未提交之前, 事务B 来读这个数据, 这个过程就是脏读, 读到的数据就是脏数据,

脏数据是指 : 无效的数据 (因为 事务A 还未提交, 可能 事务B 读完之后, 事务A 又修改了, 事务B 再读的时候就可能和上次读到的不一样 )

解决方案 :

  • 给我 “写代码的操作” 加锁, 我写完了, 别人才能看

后果 :

  • 给 “写操作” 加锁之后, “读” 和 “写” 不能并发执行, 降低了并发执行效率, 但提升了隔离性

2, 不可重复读

场景 :

  • (事先约定 : 我写完了, 室友才能看) 我把代码写完了, 对室友说: “你过来看吧”

  • 他看了一眼, 回去自己写了

  • 有一只鸡来到我的键盘上一顿乱啄, 代码被改了

  • 室友再来看的时候发现, 代码变了

事务A 提交之后, 事务B 来读这个数据, 但有可能读到 其他事务 提交的数据, 导致多次读取到的数据不一样, 这个过程就是不可重复读

解决方案 :

  • 刚才 : 给我 “写代码的操作” 加锁, 我写完了, 别人才能看
  • 现在 : 给室友 “读代码的操作” 加锁, 他读的时候, 谁也不能改数据

后果 :

  • 给 “写操作” 加锁之后, 又给 “读操作” 加锁, 进一步 降低了并发执行效率, 但提升了隔离性

3, 幻读

场景 :

  • (事先约定 : 我写完了, 室友才能看, 他看的时候, 谁也不能改) 我写好了代码, 对室友说: “你过来看吧”

  • 他看了一眼, 回去自己写了

  • 我没闲着, 他要看的代码我不碰, 我打算写其他的代码

  • 他再抬头看的时候, 发现 : “卧槽, 你背着我卷?”

事务A 提交之后, 事务B 来读这个数据, 下次再读的时候, 读到的结果没变, 但是结果集变了, 这个过程就是幻读

解决方案 :

  • 第一步 : 给我 “写代码的操作” 加锁, 我写完了, 别人才能看
  • 第二步 : 给室友 “读代码的操作” 加锁, 他读的时候, 谁也不能改数据
  • 第三步 : 必须等他告诉我 “抄完了” , 我才能碰电脑(完全串行化)

后果 :

  • 我确定写完了, 室友才能看, 室友确定看完了, 我才能继续写, 完全拒绝并发, 但隔离性达到巅峰

二、MySQL 的四种隔离级别

设置不同的事务隔离级别能够不同程度地解决脏读, 不可重复读, 幻读问题

脏读不可重复读幻读
READ UNCOMMITTED 读未提交
READ COMMITTED 读已提交
REPEATABLE READ 可重复读
SERIALIZABLE 串行化

1, READ UNCOMMITTED 读未提交

如果隔离级别设置为 “读未提交” , 那么该隔离级别的事务可以看到其他事务中未提交的数据。

该隔离级别因为可以读取到其他事务中未提交的数据,而未提交的数据可能会发生回滚,因此我们把该级别读取到的数据称之为脏数据,把这个问题称之为脏读

该隔离级别下存在 : 脏读, 不可重复读, 幻读问题


2, READ COMMITTED 读已提交

如果隔离级别设置为 “读已提交”, 那么该隔离级别的事务能读取到已经提交事务的数据,因此它可以解决脏读问题

但由于在事务的执行中还可以读取到其他事务提交的结果,所以在不同时间的相同 SQL 查询中,可能会得到不同的结果,这种现象叫做不可重复读

该隔离级别下存在 : 不可重复读, 幻读问题


3, REPEATABLE READ 可重复读 (MySQL 的默认事务隔离级别)

如果隔离级别设置为 “可重复读”,那么它能确保同⼀事务多次查询的结果⼀致。因此它可以解决不可重复读问题

但也会有新的问题,比如此级别的事务正在执行时,另⼀个事务成功的插入了某条数据,但因为它每次查询的结果都是⼀样的,所以会导致查询不到这条数据,自己重复插入时又失败(因为唯一约束的原因)。明明在事务中查询不到这条信息,但就是插入不进去,这就叫幻读

该隔离级别下 : 存在幻读问题


4, SERIALIZABLE 串行化

如果隔离级别设置为 “串行化”, 那么它会强制事务排序,多个事务不会并发,从而解决了脏读不可重复读幻读问题,但因为执行效率低,所以真正使用的场景并不多


总结

以上就是本篇的全部内容, 主要介绍了并发执行事务事存在的幻读, 不可重复读, 幻读问题, 以及四种隔离级别下能够不同程度的解决这些问题

脏读不可重复读幻读
READ UNCOMMITTED 读未提交
READ COMMITTED 读已提交
REPEATABLE READ 可重复读
SERIALIZABLE 串行化

如果本篇对你有帮助,请点赞收藏支持一下,小手一抖就是对作者莫大的鼓励啦😋😋😋~


上山总比下山辛苦
下篇文章见

在这里插入图片描述


http://www.niftyadmin.cn/n/4937097.html

相关文章

Mathematica 常见指令汇编

Mathematica 常见指令汇编 常见指令 NDSolve 求解结果的保存 sol NDSolve[{y[x] x^2, y[0] 0, g[x] -y[x]^2, g[0] 1}, {y, g}, {x, 0, 1}]; numericSoly sol[[1, 1, 2]]; numericSolg sol[[1, 2, 2]]; data Table[{x, numericSoly[x], numericSolg[x]}, {x, 0, 1, 0…

Oracle PL/SQL 类型(Type):索引表、嵌套表、变长数组、pipelined 管道

1、Oracle 新建员工表和部门表.sql。 集合类型 1、Oracle 集合是相同类型元素的组合,在集合中,使用唯一的下标来标识其中的每个元素,与 Java 的 List 很像。 2、常用集合方式: 类型语法下标元素个数初始值.extend能否存在DB中…

base64转二进制流,file文件

base64转二进制流 img标签src属性,可以直接使用base64字符串,base64需要先解码,然后再转为流 /*** Base64字符串转二进制流* param {String} dataurl Base64字符串(字符串包含Data URI scheme,例如:data:image/png;b…

微信小程序有哪几种变现途径?

纵观现在市面上的微信小程序,目前变现的途径主要有:广告变现、电商变现、游戏付费、服务付费等。 1.广告变现 广告变现是小游戏、工具类、资讯类小程序变现的主要方式。微信官方为游戏开发者提供的扶植政策,对于工具类、资讯类小程序&#…

产品经理如何突破职业瓶颈,杀出重围?

随着社会的进步和科技的发展,互联网行业从未停止过发展的脚步。而在这个充满机遇和挑战的赛道上,互联网产品经理的角色显得尤为重要。然而,随着互联网产品经理的数量逐年增加,内卷化现象也日益严重。那么,产品经理应该…

背上小书包准备面试之TypeScript篇

目录 typescript是啥?与javascript的区别? typescript数据类型? typescript中枚举类型?应用场景? typescript中接口的理解?应用场景? typescript中泛型的理解?应用场景&#xf…

790. 多米诺和托米诺平铺

题目描述&#xff1a; 主要思路&#xff1a; class Solution { public:int numTilings(int n) {long long f[n][4],mod1e97;f[0][0]1;f[0][1]f[0][2]0;f[0][3]1;for(int i1;i<n;i){f[i][0]f[i-1][3];f[i][1] (f[i-1][0]f[i-1][2])%mod;f[i][2] (f[i-1][0]f[i-1][1])%mod;f…

(leecode)密码检查

有点感觉&#xff0c;试试看~ 先贴解法&#xff0c;再说题目和思路 题解 #include <stdio.h> #include <string.h> #include <ctype.h>int main() {int N 0;scanf("%d",&N);getchar();while(N--) {char str[101] {0};scanf("%s&…