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

文章目录

  • 一、什么是事务?
  • 二、事务四大特性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 TRANSACTIONBEGIN;
  • 提交事务
--提交事务
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.mzph.cn/bicheng/58026.shtml

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

相关文章

MySQL-27.多表查询-案例

一.数据准备 -- 分类表 create table category (id int unsigned primary key auto_increment comment 主键ID,name varchar(20) not null unique comment 分类名称,type tinyint unsigned not null comment 类型 1 菜品分类 2 套餐分类,sort …

今日所学1024和1026

1 简便方法: 在文件夹里找到dll的文件路径,然后在系统变量里添加对应路径, 就不会报错了。 2关于报Qt插件的错,解决办法如下 1026Github的2FA 超级详细的github双重验证密码忘记或者获取不了了怎么办&github recovery code忘记怎么办…

计算机网络:网络层 —— IPv4 地址与 MAC 地址 | ARP 协议

文章目录 IPv4地址与MAC地址的封装位置IPv4地址与MAC地址的关系地址解析协议ARP工作原理ARP高速缓存表 IPv4地址与MAC地址的封装位置 在数据传输过程中,每一层都会添加自己的头部信息,最终形成完整的数据包。具体来说: 应用层生成的应用程序…

洛谷 P3130 [USACO15DEC] Counting Haybale P

原题链接 题目本质:线段树 感觉我对线段树稍有敏感,线段树一眼就看出来了,思路出来得也快,这道题也并不是很难。 解题思路: 这道题能看出来是线段树就基本成功一半了,区间修改区间查询,就基…

「二叉树进阶题解:构建、遍历与结构转化全解析」

文章目录 根据二叉树创建字符串思路代码 二叉树的层序遍历思路代码 二叉树的最近公共祖先思路代码 二叉搜索树与双向链表思路代码 从前序与中序遍历序列构造二叉树思路代码 总结 根据二叉树创建字符串 题目: 样例: 可以看见,唯一特殊的就…

深度学习-循环神经网络-LSTM对序列数据进行预测

项目简介: 使用LSTM模型, 对文本数据进行预测, 每次截取字符20, 对第二十一个字符进行预测, LSTM层: units100, activationrelu Dense层: units输入的文本中的字符种类, 比如我使用的文本有644个不同的字符, 那么units64 激活函数: 因为是多分类, 使用softmax 因为这是最…

使用Vue.js构建响应式Web应用

💖 博客主页:瑕疵的CSDN主页 💻 Gitee主页:瑕疵的gitee主页 🚀 文章专栏:《热点资讯》 使用Vue.js构建响应式Web应用 1 引言 2 Vue.js简介 3 安装Vue CLI 4 创建Vue项目 5 设计应用结构 6 创建组件 7 使用…

2024“源鲁杯“高校网络安全技能大赛-Misc-WP

Round 1 hide_png 题目给了一张图片,flag就在图片上,不过不太明显,写个python脚本处理一下 from PIL import Image ​ # 打开图像并转换为RGB模式 img Image.open("./attachments.png").convert("RGB") ​ # 获取图像…

GCN+BiLSTM多特征输入时间序列预测(Pytorch)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 GCNBiLSTM多特征输入时间序列预测(Pytorch) 可以做风电预测,光伏预测,寿命预测,浓度预测等。 Python代码,基于Pytorch编写 1.多特征输入单步预测…

【大数据学习 | kafka】kafuka的基础架构

1. kafka是什么 Kafka是由LinkedIn开发的一个分布式的消息队列。它是一款开源的、轻量级的、分布式、可分区和具有复制备份的(Replicated)、基于ZooKeeper的协调管理的分布式流平台的功能强大的消息系统。与传统的消息系统相比,KafKa能够很好…

MySQL-DQL练习题

文章目录 简介初始化表练习题 简介 本节简介: 主要是一些给出一些习题, 关于DQL查询相关的, DQL查询语句是最重要的SQL语句, 功能性最复杂, 功能也最强, 所以本节建议适合以及有了DQL查询基础的食用, 另外注意我们使用的是Navicat, SQL编辑的格式规范也是Navicat指定的默认格式…

Android 15: 探索未来的可能性

Android 15: 探索未来的可能性 随着技术的不断进步,我们的智能手机系统也在不断地进化。Android 15,作为谷歌最新推出的操作系统版本,带来了一系列令人兴奋的新特性和改进,让我们的数字生活更加丰富多彩。本文将带你一探Android 15的新特性,感受科技的魅力。 低光增强:…

《云原生安全攻防》-- K8s攻击案例:权限维持的攻击手法

在本节课程中,我们将一起深入了解K8s权限维持的攻击手法,通过研究这些攻击手法的技术细节,来更好地认识K8s权限维持所带来的安全风险。 在这个课程中,我们将学习以下内容: K8s权限维持:简单介绍K8s权限维持…

安装OpenResty

OpenResty OpenResty 是一个基于 Nginx的高性能 Web 平台,用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。具备下列特点: 具备Nginx的完整功能 基于Lua语言进行扩展,集成了大量精良的 Lua 库、第三方模块…

python多线程处理xlsx,多进程访问接口

import pandas as pd from concurrent.futures import ThreadPoolExecutor# 读取Excel文件 file_path scence.xlsx df pd.read_excel(file_path)# 定义每10行处理逻辑 def process_rows(start_idx):end_idx min(start_idx 10, len(df)) # 处理每10行for i in range(start_…

【Linux系统】进程终止

一、进程退出方式 1、正常终止 主要两种类型:从 main 返回、调用 exit 和 _exit 具体讲解如下: (1)从 main 返回 这个的使用就不用多说了吧,相信你们已经烂熟于心了 作用:return 语句用于从函数中返回…

一篇文章了解RocketMQ基础知识。

目录 一. 为什么选择了 RocketMQ ? 二. RocketMQ 介绍 名词说明 1. Topic (主题) 1.1 Topic 核心作用 1.2 Topic 常见问题 2. Tag (标签) 3. Queue (队列) 3.1 Queue 读写队列 4. Message (消息) 4.1 Message 类型 5. Produ…

NVR录像机汇聚管理EasyNVR多品牌NVR管理工具/设备视频报警功能详解

在科技日新月异的今天,视频监控系统作为现代社会的“第三只眼”,正以前所未有的方式深刻影响着我们的生活与社会结构。从公共场所的安全监控到个人生活的记录分享,视频监控系统以其独特的视角和功能,为社会带来了诸多好处&#xf…

day10:ssh服务-跳板机

一,ssh服务概述 ssh服务概述 ssh(Secure Shell)是一种用于在不安全网络中进行安全登录、远程执行命令及传输文件的网络协议。它通过加密技术来保证通信的保密性和完整性,主要用于替代不安全的telnet、rlogin、rsh等协议。ssh通常…

python爬虫实战案例——抓取B站视频,不同清晰度抓取,实现音视频合并,超详细!(内含完整代码)

文章目录 1、任务目标2、网页分析3、代码编写 1、任务目标 目标网站:B站视频(https://www.bilibili.com/video/BV1se41117WP/?vd_sourcee8e376ccbc5aa4cfd88e6a7917adfd1a),用于本文测验 要求:抓取该网址下的视频&…