MySql中的事务、MySql事务详解、MySql隔离级别

news2025/2/22 7:35:41
文章目录
  • 一、什么是事务?
  • 二、事务四大特性ACID
    • 2.1、原子性(Atomicity)
    • 2.2、一致性(Consistency)
    • 2.3、隔离性(Isolation)
    • 2.4、持久性(Durability)
  • 三、事务操作/事务的用法
    • 3.1、事务操作系列语法
    • 3.2、模拟转账失败(修改提交方式为手动)
  • 四、并发事务问题(脏读-幻读-不可重复读)
    • 4.1、并发事务概念
    • 4.2、并发事务问题
      • 4.2.1、脏写/更新丢失
      • 4.2.2、脏读
      • 4.2.3、不可重复读
      • 4.2.4、幻读
  • 五、事务隔离级别
    • 5.1、查看、修改事务隔离级别
  • 六、总结
    • 6.1、事务特性:
    • 6.2、隔离级别:
    • 6.3、如何手动开启事务?【默认是自动commit的】

本文详细介绍了数据库事务的概念及操作,包括事务的定义、开启、提交与回滚。

一、什么是事务?

思考:我去银行给朋友汇款,我卡上有100元,朋友卡上50元,我给朋友转账50元,如果我的钱刚扣,而朋友的钱又没加时,网线断了, 怎么办

事务:(Transaction)是数据库管理系统(DBMS)中的一个核心概念,它确保了一系列数据库操作要么全部成功,要么全部失败,从而维护数据库的完整性和一致性。

MySQL在5.5版本开始,就将InnoDB引擎作为默认存储引擎。

由于Mysql中的事务是存储引擎实现,而且只有InnoDB支持事务 ,其他常见的如MyISAM和Memory都是不支持事务的,因此我们讲解InnoDB的事务。

二、事务四大特性ACID

  • 原子性(Atomicity):原子性是指事务是一个不可分割的工作单位,事务内的操作要么都发生,要么都不发生
  • 一致性(Consistency):事务前后数据的完整性必须保持一致
  • 隔离性(Isolation):多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离。隔离性由隔离级别保障!
  • 持久性(Durability):一个事务一旦提交,他对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
    在这里插入图片描述

其中:原子性和一致性由undolog实现;隔离性由mvcc实现;持久性由redeolog实现
举个例子:
A向B转账500,转账成功,A扣除500元,B增加500元,原子操作体现在要么都成功,要么都失败
在转账的过程中,数据要一致,A扣除了500,B必须增加500
在转账的过程中,隔离性体现在A向B转账,不能受其他事务干扰
在转账的过程中,持久性体现在事务提交后,要把数据持久化(可以说是落盘操作)

2.1、原子性(Atomicity)

原子性:事务是一个不可分割的工作单位,事务中的操作要么全部执行,要么全部不执行。这确保了事务的完整性,防止了部分操作成功而部分操作失败的情况。

  • 事务是一个完整的操作,事务的各元素是不可分的。
  • 事务中的所有元素必须作为一个整体提交或回滚。
  • 如果事务中的任何元素失败,则整个事务将失败。

2.2、一致性(Consistency)

一致性:指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。

  • 当事务完成时,数据必须处于一致状态 。
  • 在事务开始前,数据库中存储的数据处于一致状态。
  • 在正在进行的事务中,数据可能处于不一致的状态。
  • 当事务成功完成时,数据必须再次回到E知的一致状态。

2.3、隔离性(Isolation)

隔离性:指在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。事务之间的操作不会互相干扰。

  • 对数据进行修改的所有并发事务是彼此隔离的,表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。

  • 修改数据的事务可在另一个使用相同数据的事务开始之前访问这些数据,或者在另一一个使用相同数据的事务结束之后访问这些数据。

  • 也就是说并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的。

  • 隔离级别

    • 未提交读(Read Uncommitted):允许脏读,即允许一个事务看到其他事务未提交的修改。这种隔离级别最低,性能最高,但一致性最差。
    • 提交读(Read Committed):只允许一个事务看到其他事务已经提交的修改。这种隔离级别可以防止脏读,但不能防止不可重复读和幻读。
    • 可重复读(Repeatable Read):确保如果在一个事务中执行两次相同的SELECT语句,都能得到相同的结果。这种隔离级别可以防止脏读和不可重复读,但不能完全防止幻读(在某些数据库系统中,如MySQL的InnoDB引擎,通过间隙锁等技术可以进一步防止幻读),MySQL默认事务级别
    • 串行化(Serializable):将事务完全隔离,使得它们按顺序执行。这种隔离级别最高,一致性最好,但性能最低。

2.4、持久性(Durability)

持久性:指事务一旦提交,它对数据库所做的更改就会永久地保存在数据库中,即使系统发生故障也不会丢失。

  • 指不管系统是否发生故障,事务处理的结果都是永久的。
  • 一旦事务被提交,事务的效果会被永久地保留在数据库中。

总结:在事务管理中,原子性是基础,隔离性是手段,一致性是目的,持久性是结果。

三、事务操作/事务的用法

3.1、事务操作系列语法

  • 查看/设置事务提交方式

    – 查看会话级自动提交设置 ON:开启自动提交 OFF:禁用自动提交
    show session variables like ‘autocommit’;

    – 注意:原命令中的 ‘lile’ 应为 ‘like’,查看全局级自动提交设置 ON:开启自动提交 OFF:禁用自动提交
    show global variables like ‘autocommit’;

    – 查看/设置事务提交方式 1: 自动提交 0:手动提交
    select @@autocommit; – 会显示 @@autocommit=1;默认为自动

    –设置事务提交方式
    set @@autocommit=0; – 手动

在这里插入图片描述

  • 开启事务

    –开启事务
    START TRANSACTION 或 BEGIN;

  • 提交事务

    –提交事务
    COMMIT ;

  • 回滚事务

    –回滚事务
    ROLLBACK;

  • 保存点

    – 设置保存点
    SAVEPOINT;
    – 设置保存点并命名为S1
    SAVEPOINT S1;

测试事务的使用及回滚

begin;
update account set money= money + 100 where name='A';
SAVEPOINT S1;
update account set money= money + 100 where name='B';
SAVEPOINT S2;
insert into account values(3,'C',1000);

select * from account;  -- 查看当前状态
ROLLBACK TO S1;  -- 回滚到S1点
select * from account;  -- 查看回滚后的状态

在这个案例中,创建了多个回滚点,并进行了多次更新和插入操作。然后,我们将事务回滚到S1 点,此时只有A的money字段被增加了100,而B的money字段和C的插入操作都被撤销了。这意味着从S1点到事务结束之间的所有操作(更新B的money和插入C的记录)都被撤销了,而S1点之前的操作(更新A的money)则保留了下来。

3.2、模拟转账失败(修改提交方式为手动)

数据准备

-- 数据准备
create table account(
    id int auto_increment primary key comment '主键ID',
    name varchar(10) comment '姓名',
    money int comment '余额'
) comment '账户表';
insert into account(id, name, money) VALUES (null,'张三',2000),(null,'李四',2000);


-- 恢复数据操作
update account set money = 2000 where name = '张三' or name = '李四';

在这里插入图片描述

代码示例:

  • 如下方代码所示,我们用程序执行报错 ...模拟抛异常
  • 此时由于我们 设置为手动提交 set @@autocommit = 0; , 所以事务并未提交;
  • 后续rollback ; 回滚事务即可;

在这里插入图片描述

-- 方式一
select @@autocommit;

set @@autocommit = 0; -- 设置为手动提交

-- 转账操作 (张三给李四转账1000)
-- 1. 查询张三账户余额
select * from account where name = '张三';

-- 2. 将张三账户余额-1000
update account set money = money - 1000 where name = '张三';

程序执行报错 ...//模拟抛异常

-- 3. 将李四账户余额+1000
update account set money = money + 1000 where name = '李四';

-- 提交事务
commit;

-- 回滚事务
rollback ;

四、并发事务问题(脏读-幻读-不可重复读)

4.1、并发事务概念

并发事务是指在数据库系统中,多个事务同时对数据进行读写和修改的过程。

对于同时运行的多个事务(多线程并发), 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题: (问题的本质就是线程安全问题,共享数据的问题)

应对措施:

  • 事务隔离机制
  • 锁机制
  • MVCC多版本并发控制隔离机制

4.2、并发事务问题

多个事务并发会导致什么问题呢?

问题

描述

脏写

一个事务修改了另一个事务已经修改但尚未提交的数据。

脏读

一个事务读到了另一个事务还未提交的数据

不可重复读

一个事务读到了另一个事务已经提交(update) 的数据。引起事务中的多次查询结果不一致。

虚读/幻读

一个事务读到了另一个事务已经插入(insert) 的数据。导致事务中多次的查询结果不一致。

在这里插入图片描述

注意:√表示可能存在的问题 ,×表示解决该问题。

4.2.1、脏写/更新丢失

脏写:一个事务修改了另一个事务已经修改但尚未提交的数据。这种情况可能会导致数据不一致性和丢失更新的问题。

具体场景:具体来说,假设有两个事务A和B,事务A修改了某条数据,但还没有提交,此时事务B也修改了同一条数据并提交了。这样就会导致事务A的修改被覆盖或丢失,从而造成数据的不一致性。

示例:

在这里插入图片描述

4.2.2、脏读

脏读:一个事务读到了另一个事务还未提交的数据脏读 (违反了事务的隔离性)

示例
例:事务A先查询id为1的数据,再修改id为1的数据。修改完以后事务A还没提交,这时候事务B也来查询id为1的数据,但这时候事务B已经可以读到A修改完的数据了。这就是脏读。(如果A事务回滚,但B已经读到了A修改的数据,造成了数据不一致)

在这里插入图片描述
在这里插入图片描述

4.2.3、不可重复读

不可重复读: 一个事务读到了另一个事务已经提交(update) 的数据。引起事务中的多次查询结果不一致。不可重复读 (违反了事务的一致性)

例:事务A先查询id为1的数据,再执行某个逻辑。这时事务B修改id为1的数据。事务A再去查询id为1的数据,却和之前不一样了!简单来说就是:在同一个事务内,查询两次同一条数据,却出现不同结果!

在这里插入图片描述

4.2.4、幻读

虚读/幻读: 一个事务读到了另一个事务已经插入(insert) 的数据。导致事务中多次的查询结果不一致。幻读 (违反了事务的隔离性)(在已经解决了不可重复读的基础上)

一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。

例:事务A查询id为1的数据,发现数据库中没有。这个时候事务B来了,正好往数据库中插入了一条id为1的数据并且提交了事务。这个时候,事务A进行插入操作,就直接报错了:里面已经有了id为1的数据(假设我们已经解决了不可重复读的问题)。但A再次进行查询,查询结果和第一次一样,发现还是没有id为1的数据,但插入就是报错,这就是幻读的问题。

注意:幻读是在解决了不可重复读的基础上,不可重复读是读取了其他事务更改的数据,针对update操作;幻读是读取了其他事务新增的数据,针对insert和delete操作。

在这里插入图片描述

五、事务隔离级别

数据库事务的隔离级别有4个,由低到高依次为:

  • 未提交读(Read Uncommitted):允许脏读,即允许一个事务看到其他事务未提交的修改。这种隔离级别最低,性能最高,但一致性最差。
  • 提交读(Read Committed):只允许一个事务看到其他事务已经提交的修改。这种隔离级别可以防止脏读,但不能防止不可重复读和幻读。
  • 可重复读(Repeatable Read)(mysql默认):确保如果在一个事务中执行两次相同的SELECT语句,都能得到相同的结果。这种隔离级别可以防止脏读和不可重复读,但不能完全防止幻读(在某些数据库系统中,如MySQL的InnoDB引擎,通过间隙锁等技术可以进一步防止幻读)。
  • 串行化(Serializable):将事务完全隔离,使得它们按顺序执行。这种隔离级别最高,一致性最好,但性能最低。

注意:事务隔离级别越高,数据越安全,但是性能越低。

这四个级别可以逐个解决脏写、脏读、不可重复读、幻读这几类问题。

隔离级别

脏读

不可重复读

幻读

READ UNCOMMITTED(读未提交)

存在

存在

存在

READ COMMITTED(读已提交)

不存在

存在

存在

REPEATABLE READ(可重复读)

不存在

不存在

存在

SERIALIZABLE(串行化)

不存在

不存在

不存在

  • 以表格列举的顺序,从上到下,隔离级别越来越高,最高级别SERIALIZABLE强制事务按顺序执行,不允许并发
  • 隔离级别越高,安全性越高,但性能越差。 选择合适的隔离级别尤为重要,既要考虑安全性又要考虑性能。
  • REPEATABLE READ(可重复读)尽管没有完全解决幻读问题,但通过多版本并发控制(MVCC)和一种称为“Next-Key Lock”的技术解决了部分幻读问题

我们在上面并发事务中提到了脏写,为什么在隔离级别中不存在脏写的问题了?
答:文上提到的4种隔离级别下,都不存在脏写情况。因为在这些隔离级别下,当两个事务A和B尝试去更新同一条数据时,假定A先更新数据,会对更新的数据行记录加上排他锁(也叫写锁,悲观锁),除非事务A提交或终止从而释放排他锁,否则事务B都是无法更新数据的。(设计数据密集型应用只是说读提交隔离级别一定可以杜绝脏写问题,并未提到读未提交隔离级别,经过实践,读未提交下事务B的更新操作也是需要等待事务A的排他锁释放,才得以执行)

5.1、查看、修改事务隔离级别

--查看事务隔离级别语法 【8.0+版本】【下面2条语句都可以查】
SELECT @@TRANSACTION_ISOLATION;
show variables like 'transaction_isolation';

--修改事务隔离级别语法
SET [SESSION|GLOBLE] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

-- 示例: 设置read committed级别:
set session transaction isolation level read committed;

设置 session 和 global 的区别:

  • session(会话级):session参数仅在当前会话(或连接)中有效
  • global(全局级):global参数是全局的,意味着改变某个系统变量的值将会对所有会话都产生影响。 需要注意的是,一旦数据库服务重启,除非在配置文件(如my.cnf或my.ini)中进行了设置,否则这些全局变量的改变就会失效。

在这里插入图片描述

六、总结

6.1、事务特性:

事务特性

描述

原子性

把事务中的所有操作看作为一个不可分割的工作单元,要么都执行,要么都不执行

一致性

保证事务开始前和事务结束后数据的完整和一致

隔离性

使多个事务并发操作同一个数据时,每个事务都有自己各自独立的数据空间,事务的执行不会受到其它事务干扰。可以通过设置隔离级别来解决不同的一致性问题

持久性

当事务被提交以后,事务中的命令操作修改的结果会被持久化保存,且不会被回滚

6.2、隔离级别:

隔离级别

允许的操作类型

备注

未提交读 (Read Uncommitted)

脏读、不可重复读、幻读

最低级别的隔离,可能会读取到其他事务未提交的更改

提交读 (Read Committed)

不允许脏读,允许不可重复读、幻读

只能读取到其他事务已经提交的更改,但同一事务内多次读取可能结果不同

可重复读 (Repeatable Read)

不允许脏读、不可重复读,有条件的允许幻读(使用InnoDB存储引擎可以解决)

保证同一事务内多次读取结果一致,但某些情况下可能产生幻读,InnoDB通过间隙锁等方式解决

串行读 (Serializable)

都不允许(相当于锁表)

最高级别的隔离,通过锁表保证事务的完全隔离,但会严重影响数据库的并发性能

在这里插入图片描述

注意:√表示可能存在的问题 ,×表示解决该问题。

6.3、如何手动开启事务?【默认是自动commit的】

-- 1、显式声明开启事务
begin;

-- 2、输入需要执行的sql语句
update user set name ='李四' where name='lisi';

-- 3、提交事务
commit;

创作不易,欢迎打赏,你的鼓励将是我创作的最大动力。

在这里插入图片描述

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

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

相关文章

10、k8s对外服务之ingress

service和ingress的作用 service的作用 NodePort:会在每个节点开放一个端口,端口号30000-32767。 也是只能用于内网访问,四层转发。实现负载均衡。不能基于域名进行访问。 clusterip:service的默认类型,只能在集群…

【STM32】舵机SG90

1.舵机原理 舵机内部有一个电位器,当转轴随电机旋转,电位器的电压会发生改变,电压会带动转一定的角度,舵机中的控制板就会电位器输出的电压所代表的角度,与输入的PWM所代表的角度进行比较,从而得出一个旋转…

个人简历html网页模板,科技感炫酷html简历模板

炫酷动效登录页 引言 在网页设计中,按钮是用户交互的重要元素之一。这样一款黑色个人简历html网页模板,科技感炫酷html简历模板,设计效果类似科技看板图,可帮您展示技能、任职经历、作品等,喜欢这种风格的小伙伴不要犹豫哦。该素材呈现了数据符号排版显示出人形的动画效…

<2.20>Leetcode哈希、双指针

还可以用双指针的做法 我们要找等于9 排序后从两边开始左右指针 2 3 7 9 如果29>9那么9肯定不能要 去掉 左边也一样 2 3 5 6 26小于9 那么2肯定不能要 去掉 package Leetcode; import java.util.*;public class 两数之和 {public int[] twoSum(int[] nums,int target…

vxe-table 如何实现跟 Excel 一样的数值或金额的负数自动显示红色字体

vxe-table 如何实现跟 Excel 一样的数值或金额的负数自动显示红色字体,当输入的值为负数时,会自动显示红色字体,对于数值或者金额输入时该功能就非常有用了。 查看官网:https://vxetable.cn gitbub:https://github.co…

【Word转PDF】在线Doc/Docx转换为PDF格式 免费在线转换 功能强大好用

在日常办公和学习中,将Word文档转换为PDF格式的需求非常普遍。无论是制作简历、撰写报告还是分享文件,都需要确保文档格式在不同设备上保持一致。而小白工具的“Word转PDF”功能正是为此需求量身打造的一款高效解决方案。 【Word转PDF】在线Doc/Docx转换…

陶瓷膜分离技术保障食品工业原料用水‌安全

陶瓷膜分离技术在食品工业中应用广泛,尤其是在保障原料用水的安全性方面发挥着重要作用。下面将从几个方面介绍陶瓷膜分离技术如何保障食品工业原料用水的安全: 高效过滤杂质:陶瓷膜具有非常细小的孔径(通常在纳米级别),能够有效去…

蓝桥杯 2.基础算法

蓝桥杯 2.基础算法 文章目录 蓝桥杯 2.基础算法基础算法时空复杂度枚举模拟编程11-16递归编程17进制转换编程18-19前缀和编程20-22差分编程23-27离散化贪心编程28-37二分双指针编程38-45构造编程46-49位运算编程50-55 排序冒泡排序选择排序插入排序快速排序归并排序编程56-65 基…

Linux中的Ctrl+C与Ctrl+Z

CtrlC与CtrlZ的区别 在Linux中,当我们在执行一个命令运行代码时,由于运行时间过长或中途出现报错,此时,我们可能需要终止该操作,这时候,该使用CtrlC还是CtrlZ呢? 1、CtrlC CtrlC:终…

【深度学习】手写数字识别任务

数字识别是计算机从纸质文档、照片或其他来源接收、理解并识别可读的数字的能力,目前比较受关注的是手写数字识别。手写数字识别是一个典型的图像分类问题,已经被广泛应用于汇款单号识别、手写邮政编码识别等领域,大大缩短了业务处理时间&…

Linux-GlusterFS操作子卷

文章目录 分布式卷添加卷分布式卷删除子卷删除总卷 🏡作者主页:点击! 🤖Linux专栏:点击! ⏰️创作时间:2025年02月20日19点30分 分布式卷添加卷 Node1上进行操作 扩容 #服务器端 gluster volu…

修改阿里云服务器内网ip

运维同事问能不能改我自己的服务内网ip, 买了一台服99元服务器,以为不能结果,结果还真改成功了, 分享一下经验。 首先最后关闭服务器-关机,必须要关闭服务 访问vpc控制台,就是要新建立一个网络 https://…

用DeepSeek零基础预测《哪吒之魔童闹海》票房——从数据爬取到模型实战

系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 文章目录 **一、为什么要预测票房?****二、准备工作****三、实战步骤详解****Step 1:数据爬取与清洗&am…

医院管理系统方案-基于蓝牙室内定位技术的院内智能导航系统:技术详解、功能设计及核心优势

文面向IT技术员、医院信息化负责人及物联网应用开发者,本文介绍了一款基于蓝牙室内定位技术的智能导航系统。该系统通过高精度定位与智能路径规划,极大提升了患者就医体验与医院运营效率。 如需获取院内智能导航系统技术文档可前往文章最下方获取&#x…

聊一聊vue如何实现角色权限的控制的

大家好,我是G探险者。 关于角色与权限控制,通常是分为两大类:一种是菜单权限;一种是操作权限。 菜单权限是指,每个角色对应着可以看到哪些菜单,至于每个菜单里面的每个按钮,比如增删改查等等这类…

TensorFlow深度学习实战——构建卷积神经网络实现CIFAR-10图像分类

TensorFlow深度学习实战——构建卷积神经网络实现CIFAR-10图像分类 0. 前言1. CIFAR-10 数据集介绍2. CIFAR-10 图像分类3. 提升模型性能3.1 增加网络深度3.2 数据增强 4. 模型测试相关链接 0. 前言 我们已经学习了卷积神经网络 (Convolutional Neural Network, CNN) 的基本概…

服务器创建conda环境并安装使用jupyter

1.创建conda环境 conda create --name myenv python3.8 conda activate myenv其中 myenv 是您想要创建的环境名称,可以根据需要替换为其他名称。2.安装juypter conda install jupyter3.启动juypter jupyter notebook复制链接到浏览器打开 4.设置jupyter使用的 …

【HarmonyOS Next】鸿蒙监听手机按键

【HarmonyOS Next】鸿蒙监听手机按键 一、前言 应用开发中我们会遇到监听用户实体按键,或者扩展按键的需求。亦或者是在某些场景下,禁止用户按下某些按键的业务需求。 这两种需求,鸿蒙都提供了对应的监听事件进行处理。 onKeyEvent 默认的…

【Spring详解五】bean的加载

五、bean的加载 当我们显示或者隐式地调用 getBean() 时,则会触发加载 bean 阶段。示例代码如下: public class AppTest {Testpublic void MyTestBeanTest() {BeanFactory bf new XmlBeanFactory( new ClassPathResource("spring-config.xml"…

ThinkPHP(TP)如何做安全加固,防webshell、防篡改、防劫持、TP漏洞防护

ThinkPHP是一款非常知名的PHP框架,很多知名CMS系统都是采用TP框架进行二次开发而来,当然ThinkPHP本身也可以直接建站,开源免费、功能强大,深受广大用户喜欢。 虽然ThinkPHP非常优秀,但是为了保障网站安全,我…