MySQL的事务总结(事务特性,隔离级别,脏读,不可重复读,幻读,常见问题)

news2025/1/9 6:02:41

MySQL的事务总结(事务四大特性,隔离级别,脏读,幻读)

MYSQL官网:https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html


1、事务(transaction)的概念

事务 是一个不可再分的最小单元,事务就是由单独单元的一个或多个sql语句组成,在这个单元中,每个sql语句都是相互依赖的。而整个单独单元是作为一个不可分割的整体存在,类似于物理概念中的的原子(不可分割的最小单位)。

通俗的说,事务就是一个整体,里面的东西要么都执行成功,要么都不成功。不会存在部分执行成功而部分执行不成功的情况。如果事务单元中某条sql语句一旦执行失败,那么整个单元将会回滚,所有受到影响的数据将返回到事务开始之前的状态,当然,如果单元中的所有sql语句都执行成功的话,那么该事务也就被顺利执行。


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

  • 原子性 (Atomicity):事务是一个不可分割的单元,要么同时成功,要么同时失败。例:当两个人发起转账业务时,如果A转账发起,而B因为一些原因不能成功接受,事务最终将不会提交,则A和B的请求最终不会成功;

  • 一致性 (Consistency):事务执行接收之后,数据库完整性不被破坏。

  • 隔离性 (Isolation):多个事务之间相互隔离的,互不干扰;

  • 持久性 (Durability):一旦事务提交,他对数据库的改变就是永久的。注:只要提交了事务,将会对数据库的数据进行永久性刷新;


3、数据库引擎对事务的支持

在MySQL中,常见的存储引擎有MyISAM、InnoDB、Memory 和 CSV 等。其中 InnoDB 支持事务(transaction),而MyISAM,Memory,CSV等不支持事务。

可通过 show engines 命令行来查看MySQL的不同引擎对事务的支持:

show engines;

查询结果:

在这里插入图片描述


4、事务的隔离级别

数据库事务的隔离级别有4种,由低到高分别为

  1. Read uncommitted 读未提交
  2. Read committed 读已提交
  3. Repeatable read 重复读
  4. Serializable 序列化

以下是具体说明:

  • 1. Read uncommitted 读未提交 以及 对应的脏读问题

读未提交,就是一个事务可以读取另一个未提交事务的数据。

举例:

A还钱给B,原本欠100块,结果不小心按成了1000块,此时1000块已经进入B的账户,但是还没有提交事务,而B这个时候正好看到账户多了1000块,然后A发现转错了,马上回滚,然后改成100块,再提交事务。

总结:那么对于B来说,它看到多出的1000块,就是脏读;怎么解决?提高隔离级 —> Read committed

  • 2. Read committed 读已提交 以及 对应的不可重复读问题

读已提交,就是只可以读取到已经提交事务的数据。

举例:

A拿着银行卡去潇洒,当他结账时,收费系统检测到卡里有500块,而此时此刻,A的老婆在另一边正好把钱转走了,并提交了事务,那么当收费系统走扣款流程时,再次检测卡里的金额,就发现余额不足;

总结:有事务对数据进行更新操作时,读操作事务要等待这个更新操作事务提交后才能读取到数据,可以解决脏读问题。但是,又出现了另一个问题:一个事务范围内两个相同的查询,结果却不一样!这就是不可重复读。怎么解决?提高隔离级别—> Repeatable read

  • 3. Repeatable read 重复读 以及 对应的幻读问题

重复读,就是在开始读取数据(事务开启)时,不再允许修改操作。

举例:

A拿着银行卡去潇洒,当他结账时,开始事务,不再允许修改操作,而此时此刻,A的老婆就转不了账,那么A就可以正常结账,收费系统正常扣款;

总结:此隔离级别可以解决不可重复读问题

但是还有没有别的问题?!

举例:

A拿着银行卡去潇洒,花了500块,然后A的老婆去查他今天的消费记录(老婆事务开启),看到确实是花了500块,此时此刻,A在回家的路上又吃了个饭,付了饭钱200块,即**新增(INSERT)**了一条消费记录,并提交了A新增的这个事务。老婆打印了一下A的消费清单(老婆事务提交),发现清单上花了700块,多出了200块,似乎出现了幻觉。

总结: 对于A的老婆来说,就是幻读。怎么解决?提高隔离级别 —> Serializable

  • 4. Serializable 序列化

最严格的隔离级别。在Serializable隔离级别下,所有事务按照次序依次执行,因此,脏读、不可重复读、幻读都不会出现
but ,鱼和熊掌不可兼得,虽然Serializable隔离级别下的事务具有最高的安全性,但由于事务是串行执行,所以效率会大大下降,应用程序的性能会急剧降低。如果没有特别重要的情景,一般都不会使用Serializable隔离级别。


5、关于脏读,不可重复读,幻读的总结

脏读: 读到了别的事务回滚前的脏数据。比如事务A执行过程中修改了id=1的数据,在未提交前,事务B读取了id=1的数据,而事务A又回滚了,这样事务B就形成了脏读。

不可重复读: 事务A首先读取了一条数据,然后执行逻辑的时候,事务B将这条数据改变了,然后事务A再次读取的时候,是A的事务修改成功后的数据,发现数据不匹配了,就是所谓的不可重复读了。

幻读: 一个事务在前后两次查询同一个范围的时候,第一次查到的数据比第二次查到的数据条目不一致。事务A首先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。

不同隔离级别与其存在的问题对应表:

隔离级别产生脏读产生不可重复读产生脏读
Read uncommitted 读未提交
Read committed 读已提交
Repeatable read 重复读
Serializable 序列化

6、数据库默认的隔离级别

mysql默认事务隔离级别为: REPEATABLE-READ 重复读(orcale默认隔离级别为: READ COMMITTED 读已提交);

  • 查看当前数据库的事务隔离级别:
 show variables like 'tx_isolation';
  • 设置事务隔离级别(4选1):
set tx_isolation='READ-COMMITTED';

7、 为什么MySQL的默认隔离离别是REPEATABLE-READ 重复读?

当设置为statement格式时,binlog记录的是SQL的原文。又因为MySQL在主从复制的过程是通过binlog进行数据同步,如果设置为读已提交/读未提交隔离级别,当出现事务乱序的时候,就会导致从库在 SQL 执行之后,结果和主库内容不一致;
因此:READ COMMITTED or READ UNCOMMITTED隔离级别下,不支持binlog的statement格式。

拓展:binlog 的三种格式:

  • Statement(Statement-Based Replication,SBR):每一条会修改数据的 SQL 都会记录在 binlog 中;
  • Row(Row-Based Replication,RBR):不记录 SQL 语句上下文相关信息,仅仅只需要记录某一条记录被修改成什么样子;
  • Mixed(Mixed-Based Replication,MBR):Statement 和 Row 的混合体,系统会自动判断该用 Statement 还是 Row:一般的语句修改使用 Statement 格式保存 binlog;对于一些 Statement无法准确完成主从复制的操作,则采用 Row 格式保存 binlog。

8、 为什么一般开发过程中选择Read Committed 隔离级别?

原因1:提升并发
因为Read committed 在加锁过程中,是不需要添加Gap Lock(间隙锁)和 Next-Key Lock(记录锁和间隙锁的组合,它指的是加在某条记录以及这条记录前面间隙上的锁),只需要对要修改的记录添加行级锁就行了。另外,RC还支持半一致读,可以大大的减少了更新语句时行锁的冲突。对于不满足更新条件的记录,可以提前释放锁,提升并发度;

原因2:减少死锁发生
因为Repeatable read会增加Gap Lock和Next-Key Lock,这就使得锁的粒度变大了,那么就容易导致死锁的概率增大。

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

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

相关文章

Git (2) :Git练习

一.首先有个问题 ? 在进行git练习前,有个问题需要提下。。。。 csdn无法登录了。 查了一下资料,是因为CSDN服务器的各地相应速度不一样,辽宁的响应是超时的,所以通过在hosts文件中指定域名http://csdnimg.cn的服务器…

音视频开发解答——门槛高,怎么样入门?知识清单一览

前言 在程序员行业中,音视频开发领域许多人接触后都觉得门槛偏高;不知道如何开始学起,网上资料很少。 看到这个问题作为行业老人,我就来说说音视频有哪些学习路线与难点? 音视频开发 音视频流媒体开发,工…

从零手写Spring(一):创建简单Bean容器

工作的前面三年,虽然一直在使用Spring,但对它却不甚了解,内心充满无数的疑问:为什么配置xml中bean就可以使用它?我的对象具体存在于哪里?为什么我的对象是单例模式? 每逢遇到面试问Spring的核…

Java---微服务---Sentinel规则持久化

Sentinel 规则持久化 一、修改微服务 修改微服务&#xff0c;让其监听Nacos中的sentinel规则配置。 具体步骤如下&#xff1a; 1.引入依赖 在order-service中引入sentinel监听nacos的依赖&#xff1a; <dependency><groupId>com.alibaba.csp</groupId>…

DPU02— USB 转 UART 桥接芯片

DPU02是一个高度集成的USB转UART的桥接控制器&#xff0c;该产品提供了一个简单的解决方案&#xff0c;可将RS-232设计更新为USB设计&#xff0c;并简化PCB组件空间。该DPU02包括了一个USB 2.0全速功能控制器、USB收发器、振荡器、EEPROM和带有完整调制解调控制信号的异步串行数…

suricata匹配从入门到精通(四)----编译lua

年前有粉丝私信我&#xff0c;想让我做一期lua脚本。作为一个宠粉的博主&#xff0c;那必须给予回应。suricata结合lua可以达到提升工作效率的作用。0x00 编译开启luna 支持&#xff1a;yum install luarocks &#xff08;不确定是否有用&#xff09;手动下载安装&#xff1a; …

Ubantu 16.04更新python版本(3.5 -> 3.9)【附:win10安装pypcap库解决办法】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、下载安装二、软连接三、下载pypcap库前言 不知道Pycharm抽什么风下不来pypcap库 百度上有回答说windows不兼容 还说的有理有据 于是只能重新捡起来ubantu了…

【手写 Promise 源码】第十二篇 - Promise.race 的实现

一&#xff0c;前言 上一篇&#xff0c;主要实现 Promise 的核心静态 API&#xff08;类方法&#xff09;&#xff1a;Promise.all&#xff0c;主要涉及以下几个点&#xff1a; 测试原生 Promise.all 的使用&#xff1b;Promise.all 的功能与特性分析&#xff1b;Promise.all…

什么是3D点云数据?该如何标注它?| 数据标注

自动驾驶汽车严重依赖输入数据来做出驾驶决策。一般来讲&#xff0c;数据越详细&#xff0c;车辆做出的决策就越好车辆行驶的也就更安全。虽然现代相机可以捕获非常详细的数据表示&#xff0c;但输出仍然是2D的&#xff0c;它限制了我们可以提供给操作车辆的神经网络的信息。相…

Java 技术知识点汇总

背景 面向百度编程&#xff0c;基本能解决大部分的问题。然而&#xff0c;技术用的熟练&#xff0c;时间久了却容易遗忘背后的技术思想&#xff0c;倒成了妥妥的搬运工了。 所以&#xff0c;偶尔针对用的技术&#xff0c;发几个灵魂拷问&#xff0c;也是很有必要的&#xff0…

Linux 软件管理 YUM管理工具 配置本地YUM源

概念引入 &#xff1a; # 首先提出一个问题&#xff0c;我们在 Linux 操作系统中是如何 安装软件的 &#xff1f;&#xff1f; >>> 在 Linux 系统中&#xff0c;安装软件是有三种方式 >>> 第一种 &#xff1a; RPM 管理工具 第二种 &#xff1a; YUM 管理工…

11、矩阵的分解

目录 一、对称正定矩阵的Cholesky分解 二、一般方阵的高斯消去法分解 三、矩形矩阵的正交分解 四、舒尔分解 矩阵分解是把一个矩阵分解成几个“较简单”的矩阵连乘的形式。在MATLAB中矩阵分解的相关函数有&#xff1a; 在MATLAB中&#xff0c;线性方程组的求解主要基于4种基…

剑指 Offer 第15天 搜索与回溯算法(中等)

目录 剑指 Offer 34. 二叉树中和为某一值的路径 剑指 Offer 36. 二叉搜索树与双向链表 剑指 Offer 54. 二叉搜索树的第k大节点 剑指 Offer 34. 二叉树中和为某一值的路径 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径…

【懒狗福音】设置Bios电源自启实现远程办公

目录前言正文需求分析开始实现需求1需求2总结前言 今年寒假升级了下家里台式机的配置&#xff0c;已经很能满足我的生产力需求。 尽管我是按着MATX主机的方向配的&#xff0c;选择的机箱也是净重较轻的铝合金材质&#xff0c;机身自带提手也还算便捷。 但是装配完毕后它的整…

前端开发:JS中数组常用方法汇总

前言 在前端开发中关于数组的使用想必前端开发者并不陌生&#xff0c;尤其是在处理业务逻辑的时候&#xff0c;从后端获取的数据类型中数组类型基本占到70%的比例&#xff0c;所以与其说是处理数据&#xff0c;不如说是处理数组&#xff0c;虽然说的有点夸张&#xff0c;前端实…

vue文件导出/下载

const blob new Blob([res.data]);const elink document.createElement(a);elink.download 导出数据.xlsx;elink.style.display none;elink.href URL.createObjectURL(blob);document.body.appendChild(elink);elink.click();URL.revokeObjectURL(elink.href);document.bo…

使用Coding管理项目代码记录

直接开门见山 一、创建项目 进入coding登录后&#xff0c;找到项目菜单&#xff0c;然后点击创建项目 二、创建代码仓库 进入项目中&#xff0c;针对不同需要创建代码仓库。大项目或者前后端分离分开开发的可以创建不同的代码仓库。 三、创建代码仓库与本地关联 项目管…

Java岗面试题--Java基础(日积月累,每日三题)

目录面试题一&#xff1a;JDK、JRE、JVM之间的区别面试题二&#xff1a;hashCode()与equals()之间的关系追问&#xff1a;为什么重写 equals() 就一定要重写 hashCode() 方法&#xff1f;面试题三&#xff1a;String、StringBuffer、StringBuilder的区别追问一&#xff1a;Stri…

vulfocus靶场通关(目录遍历)

uWSGI 目录穿越&#xff08;CVE-2018-7490&#xff09; uWSGI是一款Web应用程序服务器&#xff0c;它实现了WSGI、uwsgi和http等协议&#xff0c;并支持通过插件来运行各种语言,uWSGI 2.0.17之前的PHP插件&#xff0c;没有正确的处理DOCUMENT_ROOT检测&#xff0c;导致用户可以…

【运维】通过gotty实现网页代理访问服务器及K8S容器操作实践

Gotty 是Golang编写的可以方便的共享系统终端为web应用&#xff0c;是一个灵活强大的通过web访问终端的工具。本文将主要通过搭建Gotty实现对K8S容器的访问操作&#xff0c;开发如果想要正常的进行容器访问以及测试环境代码调试&#xff0c;最好是搭建一套与运维环境隔离的应用…