Mysql(九) --- 事务

news2024/12/25 1:58:01

文章目录

  • 前言
  • 1.什么是事务?
  • 2.事务的ACID特性
  • 3.为什么要使用事务?
  • 4.如何使用事务
    • 4.1.查看支持事务的 存储引擎
    • 4.2.语法
    • 4.3.开启一个事务,执行修改后回滚
    • 4.4.开启一个事务,执行修改后提交
    • 4.5.保存点
    • 4.6.自动/手动提交事务
  • 5.事务的隔离性和隔离级别
    • 5.1.什么是隔离性
    • 5.2.隔离级别
    • 5.3.查看和设置隔离级别
  • 6.不同隔离级别存在的问题
    • 6.1.READ UNCOMMITTED
      • 6.1.1. 出现的问题
      • 6.1.2. 代码实现
    • 6.2.READ COMMITTED
      • 6.2.1.出现的问题
      • 6.2.2. 代码的实现
    • 6.3.REPEATABLE READ
      • 6.3.1. 出现的问题
      • 6.3.2. 代码的实现
    • 6.4.SERIALIZABLE
    • 6.5.不同隔离级别的性能与安全


前言

前面博客都是在一个服务端中进行的,今天我们学习在两个服务器段进行的,看看会出现哪些意想不到的问题


1.什么是事务?

事务是一组SQL语句打包成为一个整体,在这组SQL的执行过程中,要么全部成功,要么全部失败。这组SQL语句可以是一条也可以是多条。先看一个转账的例子,如图:
在这里插入图片描述
为了完成上述的操作,我们来建立账户表

create table account(
id bigint primary key auto_increment,
name varchar(20) not null,
balance decimal(10,2) not null
);
insert into account(name,balance) values ("张三",1000);
insert into account(name,balance) values ("李四",1000);
update account set balance = balance - 100 where name = '张三';
update account set balance = balance + 100 where name = '李四';
  • 如果转账成功,应该有以下结果:
  1. 张三的账户余额减少** 100**,变成900,李四的账户余额增加了100,变成1100,不能出现张三的余额减少而李四的余额没有增加的情况;
  2. 张三和李四在发生转账前后的总额不变,也就说转账前张三和李四的余额总数为1000+1000=2000,转账后他们的余额总数为900+1100=2000
  3. 转账后的余额结果应当保存到存储介质中,以便以后读取;
  4. 以后一点需要注意,在转账的处理过程中张三和李四的余额不能因其他的转账事件而受到干扰。
    以上这四点在事务的整个执行过程中必须要得到保证,这也就是事务的ACID特性
    根据下面的图片,我们发现结果是符合上面的描述。
    在这里插入图片描述

2.事务的ACID特性

事务的ACID特性指的是Atomicity(原子性)Consistency(一致性)Isolation(隔离性)Durability(持久性)

  • Atomicity(原子性): 一个事务中所有操作,要么全部成功,要么全部失败,不会出现只执行了一半的情况,如果事务在执行过程中发生错误,会回滚(Rollback)到事务开始前的状态,就想这个事务从来没有执行过一样。
  • Consistency(一致性): 在事务开始之前和事务结束以后,数据库的完整性不会被破坏。这表示写入的数据必须完全符合所有的预设规则,包括数据的精度、关联性以及关于事务执行过程中服务器崩溃后如何恢复。
  • Isolation(隔离性): 数据库允许多个并发事务同时对数据进行读写和修改,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一样。事务可以指定不同的隔离级别,以权衡在不同的应用场景下数据库性能和安全
  • Durability(持久性): 事务处理结束后,对数据的修改将永久的写入存储介质中,即使系统故障也不会丢失。

3.为什么要使用事务?

事务具备的ACID特性,是我们使用事务的原因,在我们日常的业务场景中有大量的需求要用事务来保证。支持事务的数据库能够简化我们的编程模型,不需要我们去考虑各种各样的潜在错误和并发问题,在使用事务过程中,要么提交,要么回滚,不用去考虑网络异常,服务器宕机等其他因素,因此我们经常接触的事务本质上是数据库对 ACID 模型的⼀个实现,是为应用层服务的


4.如何使用事务

4.1.查看支持事务的 存储引擎

要使用事务那么数据库就要支持事务,在MySQL中支持事务的存储引擎是InnoDB,可以通过

show engines;

在这里插入图片描述

4.2.语法

通过以下语句可以完成对事务的控制

  1. #开启一个事务
  2. start transaction;
  3. #或
  4. begin;
  5. #提交事务,并对更改持久化保存
  6. commit;
  7. #回滚当前事务,取消其更改
  8. rollback;
  • start transactionbegin 开始一个新事务
  • commit 提交当前事务,并对更改持久化保存
  • rollback 回滚当前事务,取消其更改
  • 无论提交还是回滚,事务都会关闭

4.3.开启一个事务,执行修改后回滚

示例:张三的余额减少100,李四的余额增加100,最后回滚到初始状态
第一步:开启事务

start transaction;

在这里插入图片描述

第二步:查看account表

select * from account;

在这里插入图片描述

第三步:将张三的余额减少100,李四的余额增加100

update account set balance = balance - 100 where name = '张三';
update account set balance = balance + 100 where name = '李四';

在这里插入图片描述

第四步:查看结果集

select * from account;

在这里插入图片描述

第五步:回滚到最开始的位置

rollback;

在这里插入图片描述

最后:查看结果集,是否跟最开始的一样

select * from account;

在这里插入图片描述
结束。

4.4.开启一个事务,执行修改后提交

示例:张三的余额减少100,李四的余额增加100,最后提交。
其实跟上面的流程都一样,我只把代码写一下,大家敲一下,看看结果就知道了。

start transaction;
select * from account;
update account set balance = balance - 100 where name = '张三';
update account set balance = balance + 100 where name = '李四';
select * from account;
commit;
select * from account;

在这里插入图片描述

4.5.保存点

在事务执行的过程中设置保存点,回滚时指定保存点可以把数据恢复到保存点的状态
语法:

savepoint 保存点的名字;

示例:分别进行下面三个步骤,分别设置一个保存点,然后进行回滚,看看结果集情况

  1. 张三的余额减少100,李四的余额增加100
  2. 张三的余额减少100,李四的余额增加100
  3. 插入一条消息,王五,余额3000

(先说好哦,前面如果commit那些操作过的话,张三的余额是900,李四的余额是1100,记得要把张三的余额变为1000,李四的余额变为1000,不然张三同学不高兴的)

start transaction;
select * from account;
-- 第一步:张三的余额减少100,李四的余额增加100
update account set balance = balance - 100 where name = '张三';
update account set balance = balance + 100 where name = '李四';
select * from account;
-- 设置保存点1
savepoint sp1;
-- 第二步:张三的余额减少100,李四的余额增加100
update account set balance = balance - 100 where name = '张三';
update account set balance = balance + 100 where name = '李四';
select * from account;
-- 设置保存点2
savepoint sp2;
-- 第3步:插入一条消息,王五,余额3000
insert into account values(null,'王五',3000);
select * from account;
-- 设置保存点3
savepoint sp3;
-- 回滚到保存点2
rollback to sp2;
-- 查看结果集
select * from account;
-- 回滚最初的时候
rollback;

如果在设置完保存点3的时候,如果直接回滚到了sp1这个位置的话,就无法回滚到sp2或sp3这个位置了。具体的内容,大家操作一下,必要的时候,可以对上面的代码进行修改。

4.6.自动/手动提交事务

默认情况下,MySQL是自动提交事务的,也就是说我们执行的每个修改操作,比如插入、更新和删除,都是自动开启一个事务并在语句执行完成之后自动提交,发生异常时自动回滚。
查看当前事务是否自动提交

show variables like 'autocommit';

在这里插入图片描述

可以使用一下的操作来禁止或者开启事务是否自动提交
自动提交

set autocommit = 1;

或者

set autocommit = on;

手动提交

set autocommit = 0;

或者

set autocommit = off;

在这里插入图片描述
注意:

  • 只要使用 START TRANSACTION 或 BEGIN 开启事务,必须要通过 COMMIT 提交才会持久化,与是否设置 SET autocommit 无关。
  • 手动提交模式下,不用显示开启事务,执行修改操作后,提交或回滚事务时直接使用commit或 rollback
  • 已提交的事务不能回滚

5.事务的隔离性和隔离级别

5.1.什么是隔离性

MySQL服务可以同时被多个客户端访问,每个客户端执行的DML语句以事务为基本单位,那么不同的客户端在对同一张表中的同一条数据进行修改的时候就可能出现相互影响的情况,为了保证不同的事务之间在执行的过程中部首影响,那么事务之间就需要相互隔离,这种特性就是隔离性

5.2.隔离级别

事务具有隔离性,那么如何实现事务之间的隔离?隔离到什么程度?如何保证数据安全的同时也要兼顾性能?这都是要考虑的问题。
事务之间不同程度的隔离,称为事务的隔离级别,不同的隔离级别在性能和安全方面做了取舍,有的隔离级别注重并发性,有的注重安全性,有的则是并发和安全适中,在MySQL的InnoDB引擎中事务的隔离级别有四种,分别是:

  • READ UNCOMMITTED,读未提交
  • READ COMMITTER,读已提交
  • REPEATABLE READ,可重复读(默认)
  • SERIALIZABLE,串行化
    *在这里插入图片描述

5.3.查看和设置隔离级别

  • 事务的隔离级别分为全局作用域和会话作用域,查看不同作用域事务的隔离级别,可以使用以下的方式:
-- 全局变量
select @@GLOBAL.transaction_isolation;
-- 会话作用域
select @@SESSION.transaction_isolation;

在这里插入图片描述

  • 设置事务的隔离级别和访问模式,可以使用以下语法:
select [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL level|access_mode;

隔离级别:
level:{
REPEATABLE READ # 可重复度
|READ COMMITTED #读已提交
|READ UNCOMMITTED # 读未提交
|SERIALIZABLE # 串行化
}
访问模式:
access_mode:{
READ WRITE # 表示事务可以对数据进行读写
| READ ONLY # 表示事务是只读,不能对数据进行读写
}

示例:
1.设置全局事务隔离级别为串行化,后续所有事务生效,不影响当前事务

set global transaction isolation level serializable;

在这里插入图片描述
2. 设置全局事务隔离级别为串行化,后续所有事务生效,不影响当前事务

set session transaction isolation level serializable;

3 如果不指定任何作用域,设置只针对下一个事务,随后的事务恢复之前的隔离级别

set global transaction_isolation = 'repeatable-read';

或者

set session transaction_isolation = 'seriablizable';

6.不同隔离级别存在的问题

接下的过程都需要两个MySQL的客户端,大家提前准备两个客户端,分别是客户端A和客户端B

6.1.READ UNCOMMITTED

6.1.1. 出现的问题

出现在事务的 READ UNCOMMITTED 隔离级别下,由于在读取数据时不做任何限制,所以并发性能很高,但是会出现量的数据安全问题,比如在事务A中执行了一条 INSERT 语句,在没有执行COMMIT 的情况下,会在事务B中被读取到,此时如果事务A执行回滚操作,那么事务B中读取到事务A写入的数据将没有意义,我们把这个现象叫做 “脏读”

6.1.2. 代码实现

首先先把隔离级别设置为 READ UNCOMMITTED

set global transaction isolation level read uncommitted;

考虑到 Markdown版本中表格里是不能添加代码段的,因此只能以图片的形式进行展示
在这里插入图片描述

6.2.READ COMMITTED

6.2.1.出现的问题

为了解决脏读的问题,可以把事务的隔离级别设置为READ COMMITTED,这时事务只能读到其他事务提交之后的数据,但会出现不可重复读的问题,比如事务A先对某条数据进行了查询,之后事务B对这条数据进行了修改,并且提交(COMMIT)事务,事务A再对这条数据进行查询时,得到了事务B修改之后的数据,这导致了事务A在同一个事务中以相同的条件查询得到了不同的值,这个现象叫做 “不可重复读”

6.2.2. 代码的实现

首先把隔离级别设置为 READ COMMITTED

SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

在这里插入图片描述

6.3.REPEATABLE READ

6.3.1. 出现的问题

为了解决不可重复读这个问题,可以把事务的隔离级别设置为REPEATABLE READ,这时同一个事务中读取的数据在任何时候都是相同的结果,但还会出现一个问题,事务A查询了一个区间的记录得到结果集A事务B向这个区间的间隙中写入了一条记录并提交,事务A在查询这个区间的结果集时会查到事务B新写入的记录得到结果集B,再次查询的结果集不一致,这个现象就是 “幻读”

MySQL的InnoDB存储引擎使用了Next-key解决了大部分幻读问题

6.3.2. 代码的实现

由于 REPEATABLE READ 隔离级别默认使用了 Next-Key 锁,为了重现幻读问量,我们把隔离级回退到更新时只加了排他锁的 READ COMMITTED
首先把隔离级别设置为 READ COMMITTED

SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

在这里插入图片描述


6.4.SERIALIZABLE

进⼀步提升事务的隔离级别到 SERIALIZABLE ,此时所有事务串行执行,可以解决所有并发中的安全问题


6.5.不同隔离级别的性能与安全

隔离级别脏读不可重复读幻读
READ UNCOMMITTED存在存在存在
READ COMMITTED解决存在存在
REPEATABLE READ解决解决存在
SERIALIZABLE解决解决解决

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

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

相关文章

[含文档+PPT+源码等]精品大数据项目-springboot基于Hadoop框架实现的高校图书馆阅读书目推荐系统

关于大数据项目——Spring Boot基于Hadoop框架实现的高校图书馆阅读书目推荐系统的课题背景,可以从以下几个方面进行阐述: 一、信息技术发展的推动 随着信息技术的迅猛发展,互联网上的信息数据量呈爆炸式增长。这种信息过载现象使得用户难以…

2014年国赛高教杯数学建模A题嫦娥三号软着陆轨道设计与控制策略解题全过程文档及程序

2014年国赛高教杯数学建模 A题 嫦娥三号软着陆轨道设计与控制策略 嫦娥三号于2013年12月2日1时30分成功发射,12月6日抵达月球轨道。嫦娥三号在着陆准备轨道上的运行质量为2.4t,其安装在下部的主减速发动机能够产生1500N到7500N的可调节推力,…

如何优雅的通过Spring Boot+Redission对订单实现定时关闭

简介 在电子商务及支付相关平台中,常规流程是首先生成订单或支付请求,用户随后会在规定时间内完成支付。如果用户未能在预设时限内完成支付动作,系统通常会执行相应的过期处理机制,即自动取消未支付的订单。 此外,这…

鸿蒙开发之ArkUI 界面篇 三十一 Extend(封装)

开发中遇到重复使用次数多的代码,就是封装提取成一个方法,那么鸿蒙中的方法是怎么封装的呢?下面记录组件属性的封装,语法格式如下: Extend(组件名) function 函数名 (参数, 参数2) { } 例如:封装一个Text…

飞机大战ai通过dqn实现

借鉴 飞机大战源码 github 王者荣耀ai训练(试了一下,发现电脑带不动,就改了一点,训练其他游戏) 源码 通过网盘分享的文件:PlaneWar (2).zip [链接](https://pan.baidu.com/s/1N4OorR7b36Zml8MadGmI6g?pwd1234&#xf…

6.将扩散模型与其他生成模型的关联(2)

1.归一化流与扩散模型 自一化流(Normalizing Flow)是生成模型,通过将易于处理的分布进行变换以队对高维数据进行建模。归一化流可以将简单的概率分布转化为极其复杂的分布,并用于强化学习、变分推理等领域。 现有的归一化流是基于变量替换公式构…

GS-LRM: Large Reconstruction Modelfor 3D Gaussian Splatting 论文解读

目录 一、概述 二、相关工作 1、多视图的三维重建 2、前馈重建 三、LRM 1、编码器 2、解码器 3、NeRF渲染 四、GS-LRM 1、输入处理 2、Transformer 3、损失函数 五、实验 六、局限 一、概述 该论文提出了一种利用稀疏输入图像高效预测3D高斯原语的方法&#xff…

数据结构-5.6.二叉树的先,中,后序遍历

一.遍历: 二.二叉树的遍历:利用了递归操作 1.简介: 二叉树的先序遍历,中序遍历,后序遍历都是以根结点遍历顺序为准的,如先序遍历就先遍历根结点 2.实例: 例一: 例二: …

【LeetCode】动态规划—188. 买卖股票的最佳时机 IV(附完整Python/C++代码)

动态规划—188. 买卖股票的最佳时机 IV 题目描述前言基本思路1. 问题定义交易规则: 2. 理解问题和递推关系两种情况:状态定义:状态转移方程:初始条件: 3. 解决方法动态规划方法特殊情况:当 k 大于等于 pric…

【最新华为OD机试E卷-支持在线评测】构成正方形的数量(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

(全网独家)面试要懂运维真实案例:HDFS重新平衡(HDFS Balancer)没触发问题排查

在面试时,面试官为了考察面试者是否真的有经验,经常会问运维集群时遇到什么问题,解决具体流程。下面是自己遇到HDFS Balancer没执行,花了半天时间进行排查,全网独家的案例和解决方案。 目录 使用CDH自带重新平衡操作…

数据结构 ——— 顺序表oj题:最长公共前缀

目录 题目要求 代码实现 题目要求 编写一个函数来查找字符串数组中的最长公共前缀,如果不存在公共前缀,返回空字符串 "" 代码实现 代码演示: void CommonPrefix(char** strs, int strsSize, char* returnStr) {char* first_r…

利用session机制造测试账号,无需前端也可以测试后端接口

适用场景:我们在测试的时候经常会遇到前端还没有开发完毕,后端已经结束开发了,但是后端的有些接口是需要特定的账号身份调用才会生效,此时因为前端未开发完毕,所以我们不能通过web页面进行登录,那么如何解决…

【Python Django + Vue】酒店在线预订系统:用技术说话!

🎓 作者:计算机毕设小月哥 | 软件开发专家 🖥️ 简介:8年计算机软件程序开发经验。精通Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等技术栈。 🛠️ 专业服务 🛠️ 需求定制化开发源码提…

Parallels Desktop意外退出,Parallels Desktop安装软件很卡闪退怎么办?

Parallels Desktop是目前很优秀的虚拟机软件,操作简单,兼容性强而且安装也非常方便,备受苹果用户的喜爱和满意。然而,部分用户在使用Parallels Desktop的时候,会遇到意外退出或终端关机的情况,这不仅会影响…

VS2017 编译 SQLite3 动态库

首先官方下载源码: Tags sqlite/sqlite (github.com) 1.安装 VS2017 community edition 2.打开VS2017命令行工具 3.安装TCL 开发库,推荐 TCL 9.0 先下载源码: Tcl/Tk 9.0 使用vs2017编译tcl&

CRC码计算原理:按位讲解计算过程

CRC8 这里先以CRC8来说明CRC的计算过程 1、CRC8在线计算器 通过CRC在线计算器可以看见CRC8的特征多项式:x8x2x1,初始值为0000’0000。 CRC计算的核心是:反转异或移位(此处的CRC8没有涉及反转,见后面CRC16&#xff0…

基于Langchain框架下Prompt工程调教大模型(LLM)[输入输出接口、提示词模板与例子选择器的协同应用

大家好,我是微学AI,今天给大家介绍一下基于Langchain框架下Prompt工程调教大模型(LLM)[输入输出接口、提示词模板与例子选择器的协同应用。本文深入探讨了Langchain框架下的Prompt工程在调教LLM(大语言模型)方面的应用&#xff0c…

C++入门基础知识110—【关于C++嵌套 if 语句】

成长路上不孤单😊😊😊😊😊😊 【14后😊///C爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于C 嵌套 if 语句的相关内容! …

全院级、流程化的医院安全不良事件管理系统源码——等级医院评审工作的辅助工具

前言: 冰山理论”指出“每件严重不良事件背后可能隐藏着10件轻微的不良事件”“存在30件未造成伤害的差错可能存在600件引发意外的异常事件”没有一件不良事件应该被忽视! 一项研究也指出95%医生曾目睹错误的发生,61%的医务人员认为医疗错误…