MySQL --事务(上)

news2024/11/20 11:19:52

文章目录

  • 1.什么是事务
    • 1.1为什么会出现事务
    • 1.2 事务的版本支持
    • 1.3 事务提交方式
    • 1.4事务常见操作方式
      • 1.4.1正常演示 - 证明事务的开始与回滚
      • 1.4.2非正常演示1 - 证明未commit,客户端崩溃,MySQL自动会回滚(隔离级别设置为读未提交)
      • 1.4.3非正常演示2 - 证明commit了,客户端崩溃,MySQL数据不会在受影响,已经持久化
  • 2.事务隔离级别
    • 2.1如何理解隔离性
    • 2.2隔离级别
    • 2.3 查看与设置隔离性
    • 2.4 读未提交(Read Uncommitted)
    • 2.5读已提交(Read Committed)
    • 2.6可重复读(Repeatable Read)
    • 2.7可串行化(Serializable)
    • 2.7总结

1.什么是事务

事务就是一组DML语句组成,这些语句在逻辑上存在相关性,这一组DML语句要么全部成功,要么全部失败,是一个整体。MySQL提供一种机制,保证我们达到这样的效果。事务还规定不同的客户端看到的数据是不相同的。

事务就是要做的或所做的事情,主要用于处理操作量大,复杂度高的数据。假设一种场景:你毕业了,学校的教务系统后台 MySQL 中,不在需要你的数据,要删除你的所有信息(一般不会:) ), 那么要删除你的基本信息(姓名,电话,籍贯等)的同时,也删除和你有关的其他信息,比如:你的各科成绩,你在校表现,甚至你在论坛发过的文章等。这样,就需要多条 MySQL 语句构成,那么所有这些操作合起来,就构成了一个事务。

正如我们上面所说,一个 MySQL 数据库,可不止你一个事务在运行,同一时刻,甚至有大量的请求被包装成事务,在向 MySQL 服务器发起事务处理请求。而每条事务至少一条 SQL ,最多很多 SQL ,这样如果大家都访问同样的表数据,在不加保护的情况,就绝对会出现问题。甚至,因为事务由多条 SQL 构成,那么,也会存在执行到一半出错或者不想再执行的情况,那么已经执行的怎么办呢?

所有,一个完整的事务,绝对不是简单的 sql 集合,还需要满足如下四个属性:

原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交( Read uncommitted )、读提交( read committed )、可重复读(repeatable read )和串行化( Serializable )

持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

上面四个属性,可以简称为 ACID 。

原子性(Atomicity,或称不可分割性)
一致性(Consistency)
隔离性(Isolation,又称独立性)
持久性(Durability)。

1.1为什么会出现事务

事务被 MySQL 编写者设计出来,本质是为了当应用程序访问数据库的时候,事务能够简化我们的编程模型,不需要我们去考虑各种各样的潜在错误和并发问题.可以想一下当我们使用事务时,要么提交,要么回滚,我们不会去考虑网络异常了,服务器宕机了,同时更改一个数据怎么办对吧?因此事务本质上是为了应用层服务的.而不是伴随着数据库系统天生就有的.

备注:我们后面把 MySQL 中的一行信息,称为一行记录

1.2 事务的版本支持

在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务, MyISAM 不支持。

查看数据库引擎

show engines \G

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

1.3 事务提交方式

事务的提交方式常见的有两种:
自动提交
手动提交

查看事务提交方式:

show variables like 'autocommit';

在这里插入图片描述
用 SET 来改变 MySQL 的自动提交模式:

SET AUTOCOMMIT=0;
show variables like 'autocommit';

#SET AUTOCOMMIT=0 禁止自动提交

在这里插入图片描述

SET AUTOCOMMIT=1;
show variables like 'autocommit';

#SET AUTOCOMMIT=1 开启自动提交

在这里插入图片描述

1.4事务常见操作方式

创建测试表

create table if not exists account(
id int primary key,
name varchar(50) not null default '',
blance decimal(10,2) not null default 0.0
)ENGINE=InnoDB DEFAULT CHARSET=UTF8;

1.4.1正常演示 - 证明事务的开始与回滚

– 查看事务是否自动提交。我们故意设置成自动提交,看看该选项是否影响begin

show variables like 'autocommit';

在这里插入图片描述
– 开始一个事务begin也可以,推荐begin

start transaction;

– 创建一个保存点save1

 savepoint save1;

– 插入一条记录

 insert into account values (1, '张三', 100);

– 创建一个保存点save2

savepoint save2;

– 在插入一条记录

 insert into account values (2, '李四', 10000);

在这里插入图片描述

查看

select * from account;

在这里插入图片描述
– 两条记录都在了

– 回滚到保存点save2

rollback to save2;
select * from account;

在这里插入图片描述
– 一条记录没有了

–直接rollback,回滚到最开始

rollback;
select * from account;

在这里插入图片描述
–刚刚的记录没有了

1.4.2非正常演示1 - 证明未commit,客户端崩溃,MySQL自动会回滚(隔离级别设置为读未提交)

 select * from account;
  show variables like 'autocommit';

在这里插入图片描述
– 当前表内无数据
– 依旧自动提交

–开启事务

 begin;

– 插入记录

 insert into account values (1, '张三', 100);
 select * from account;

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

1.4.3非正常演示2 - 证明commit了,客户端崩溃,MySQL数据不会在受影响,已经持久化

mysql> select * from account; -- 当前表内无数据
Empty set (0.00 sec)
mysql> begin; -- 开启事务
Query OK, 0 rows affected (0.00 sec)
mysql> insert into account values (1, '张三', 100); -- 插入记录
Query OK, 1 row affected (0.00 sec)
mysql> commit; --提交事务
Query OK, 0 rows affected (0.04 sec)
mysql> Aborted -- ctrl + \ 异常终止MySQL
--终端 B
mysql> select * from account;

在这里插入图片描述
–数据存在了,所以commit的作用是将数据持久化到MySQL中

结论:
只要输入begin或者start transaction,事务便必须要通过commit提交,才会持久化,与是否设置set autocommit无关。

事务可以手动回滚,同时,当操作异常,MySQL会自动回滚

对于 InnoDB 每一条 SQL 语言都默认封装成事务,自动提交。(select有特殊情况,因为MySQL 有 MVCC )

从上面的例子,我们能看到事务本身的原子性(回滚),持久性(commit)

事务操作注意事项

如果没有设置保存点,也可以回滚,只能回滚到事务的开始。直接使用 rollback(前提是事务还没有提交)

如果一个事务被提交了(commit),则不可以回退(rollback)

可以选择回退到哪个保存点

InnoDB 支持事务, MyISAM 不支持事务

开始事务可以使 start transaction 或者 begin

2.事务隔离级别

2.1如何理解隔离性

MySQL服务可能会同时被多个客户端进程(线程)访问,访问的方式以事务方式进行

一个事务可能由多条SQL构成,也就意味着,任何一个事务,都有执行前,执行中,执行后的阶段。而所谓的原子性,其实就是让用户层,要么看到执行前,要么看到执行后。执行中出现问题,可以随时回滚。所以单个事务,对用户表现出来的特性,就是原子性。

但,毕竟所有事务都要有个执行过程,那么在多个事务各自执行多个SQL的时候,就还是有可能会出现互相影响的情况。比如:多个事务同时访问同一张表,甚至同一行数据。

数据库中,为了保证事务执行过程中尽量不受干扰,就有了一个重要特征:隔离性

数据库中,允许事务受不同程度的干扰,就有了一种重要特征:隔离级别

2.2隔离级别

读未提交【Read Uncommitted】: 在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。(实际生产中不可能使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多并发问题,如脏读,幻读,不可重复读等,我们上面为了做实验方便,用的就是这个隔离性。

读提交【Read Committed】 :该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别会引起不可重复读,即一个事务执行时,如果多次 select, 可能得到不同的结果。

可重复读【Repeatable Read】: 这是 MySQL 默认的隔离级别,它确保同一个事务,在执行中,多次读取操作数据时,会看到同样的数据行。但是会有幻读问题。

串行化【Serializable】: 这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决了幻读的问题。它在每个读的数据行上面加上共享锁,。但是可能会导致超时和锁竞争(这种隔离级别太极端,实际生产基本不使用)

隔离级别如何实现:隔离,基本都是通过锁实现的,不同的隔离级别,锁的使用是不同的。常见有,表锁,行锁,读锁,写锁,间隙锁(GAP),Next-Key锁(GAP+行锁)等。不过,我们目前现有这个认识就行,先关注上层使用。

2.3 查看与设置隔离性

–查看全局隔级别

SELECT @@global.transaction_isolation;

在这里插入图片描述
–查看会话(当前)全局隔级别

 SELECT @@session.transaction_isolation;

在这里插入图片描述

 SELECT @@transaction_isolation;

默认同上
在这里插入图片描述

set session transaction isolation level serializable; -- 串行化

在这里插入图片描述
–全局隔离性还是RR

在这里插入图片描述
–会话隔离性成为串行化

在这里插入图片描述
–同上

–设置全局隔离性,另起一个会话,会被影响

set global transaction isolation level READ UNCOMMITTED;

在这里插入图片描述
– 注意,如果没有现象,关闭mysql客户端,重新连接。

2.4 读未提交(Read Uncommitted)

定义:允许事务读取未被其他事务提交的变更。
问题:可能导致脏读,即一个事务读取了另一个事务未提交的数据。
适用场景:适用于对数据一致性要求不高,但需要高并发性能的场景。

示例:

1.场景设置:有两个客户端A和B,它们同时连接到数据库,并尝试修改同一张表(例如,表名为account,包含用户的余额信息)。

2.客户端A操作:
A打开一个事务,设置事务模式为读未提交(read uncommitted)。
A查询表account的初始值,比如某个用户的余额是500。

客户端B操作:
在A的事务提交之前,B也打开一个事务,并更新表account中该用户的余额为400(但B的事务尚未提交)。
A的查询结果:尽管B的事务还未提交,A仍然能够查询到B已经更新的余额值400。
问题发生:如果B的事务因为某种原因回滚,所有操作都将被撤销,那么A之前查询到的400就是脏数据。

2.5读已提交(Read Committed)

定义:一个事务只能读取已经被其他事务提交的数据。
问题:可能出现不可重复读,即在同一事务内,多次读取同一数据集合时,由于其他事务的插入、删除或更新操作,导致每次读取的数据集合不一致。
适用场景:大多数数据库系统的默认隔离级别,适用于需要一定数据一致性但又不希望事务执行过程中数据被锁定的场景。

示例:

1.场景设置:同样有两个客户端A和B,它们连接到数据库并尝试修改同一张表(account)。

2.客户端A操作:
A打开一个事务,设置事务模式为读已提交(read committed)。
A查询表account的初始值。

3.客户端B操作:
在A的事务提交之前,B也打开一个事务,并更新表account中某条记录的值。

4.A的查询结果:由于B的事务还未提交,A此时查询不到B已经更新的数据,只能查询到事务开始前的数据。

5.B提交事务:B提交事务后,A再次执行相同的查询,此时能够查询到B更新后的数据。

6.问题:这种情况下,A在同一个事务中多次查询同一数据时,可能会因为其他事务的提交而导致查询结果不一致,即不可重复读问题。

2.6可重复读(Repeatable Read)

定义:保证在同一个事务中多次读取同样记录的结果是一致的。
问题:虽然解决了不可重复读的问题,但仍然存在幻读,即当事务重新读取一个范围的记录时,由于其他事务的插入操作,导致出现了新的记录。
适用场景:适用于需要确保在同一事务中多次读取数据结果一致的场景,如银行系统的账户余额查询。

示例:
1.场景设置:客户端A和B再次尝试修改同一张表(account)。

2.客户端A操作:
A打开一个事务,设置事务模式为可重复读(repeatable read)。
A查询表account的所有记录,并记录下某个用户的余额。

3.客户端B操作:
在A的事务提交之前,B打开一个事务,并更新该用户的余额并提交事务。

4.A的查询结果:A在同一个事务中再次查询表account的所有记录时,发现查询结果与之前一致,即B的更新对A不可见。这解决了不可重复读的问题。

5.A的更新操作:A尝试更新该用户的余额,由于使用了可重复读的隔离级别和MVCC机制,A的更新操作是基于事务开始时读取的数据快照进行的,因此即使B已经更新了余额,A的更新也不会受到影响(除非A明确读取了B更新后的数据)。

2.7可串行化(Serializable)

定义:通过强制事务串行执行,避免脏读、不可重复读和幻读。
问题:虽然提供了最高的数据一致性和隔离性,但会显著降低系统的并发性能。
适用场景:适用于对数据一致性要求极高,且可以接受较低并发性能的场景。

需要注意的是,由于可串行化隔离级别的实现细节依赖于具体的数据库系统,因此在实际应用中可能会有所不同。此外,由于强制事务串行执行可能会严重影响性能,因此在实际应用中通常会根据具体的需求和场景来选择合适的隔离级别。

2.7总结

隔离级别越严格,安全性越高,但数据库的并发性能也就越低,往往需要在两者之间找一个平衡点。

不可重复读的重点是修改和删除:同样的条件, 你读取过的数据,再次读取出来发现值不一样了幻读的重点在于新增:同样的条件, 第1次和第2次读出来的记录数不一样

说明: mysql 默认的隔离级别是可重复读,一般情况下不要修改

在这里插入图片描述

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

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

相关文章

Ubuntu环境切换到服务器某个用户后source等命令和Tab快捷补全都用不了了,提示没找到,但root用户可以

以escs用户为例: 输入以下命令 grep root /etc/passwd grep escs /etc/passwd 对比发现,root用户配的是bash,而escs却是sh, 所以把escs的sh改成和root一样的bash,命令为 usermod -s /bin/bash escs 改好后就可以了。 …

Win11 安装 PostgreSQL 数据库,两种方式详细步骤

文章目录 一、exe文件安装 (推荐)下载安装包1. 选择操作系统2. 跳转到EDB(PostgreSQL 的安装包托管在 EDB上)3. 选择版本点击下载按钮 安装1. 管理员打开安装包2. 选择安装目录3. 勾选安装项4. 设置数据存储目录5. 设置管理员密码…

C语言线程编程深度解析

文章目录 前言一、线程基础概念1. 什么是线程?2. 线程与进程的区别 二、POSIX线程库(pthread)1. pthread简介2. 编译与链接3. 创建线程示例代码: 4. 线程同步互斥锁(Mutex)示例代码: 条件变量&a…

SpringBoot代码实战(MyBatis-Plus+Thymeleaf)

构建项目 修改pom.xml文件&#xff0c;添加其他依赖以及设置 <!--MyBatis-Plus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.6</version><…

智源研究院与百度达成战略合作 共建AI产研协同生态

2024年9月24日&#xff0c;北京智源人工智能研究院&#xff08;简称“智源研究院”&#xff09;与北京百度网讯科技有限公司&#xff08;简称“百度”&#xff09;正式签署战略合作协议&#xff0c;双方将充分发挥互补优势&#xff0c;在大模型等领域展开深度合作&#xff0c;共…

共享打印机无法创建打印作业原因分析及解决方法

在日常办公和生活中&#xff0c;打印机是不可或缺的重要设备。然而&#xff0c;有时在添加打印机的过程中&#xff0c;经常会遇各种问题。今天有个小伙伴问我在访问共享打印机时提示“无法创建打印作业”怎么回事&#xff1f;今天小编就教大家共享打印机无法创建打印作业原因分…

多表查询。

一、多表查询 select * from 表名,表名; select * from 表名,表名 where 条件; 二、内连接 隐式 select 字段列表 from 表1,表2 where 条件; 显示 select 字段列表 from 表1 INNER JOIN 表2 on 条件; 三、外连接 1.左外连接 select 字段列表 from 表1 left [outer] join 表…

接口自动化测试框架详解(pytest+allure+aiohttp+ 用例自动生成)

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 近期准备优先做接口测试的覆盖&#xff0c;为此需要开发一个测试框架&#xff0c;经过思考&#xff0c;这次依然想做点儿不一样的东西。 接口测试是比较讲究效…

【C++】STL--string(下)

1.string类对象的修改操作 erase&#xff1a;指定位置删除 int main() {string str1("hello world");str1.push_back(c);//尾插一个ccout << str1 << endl;string str2;str2.append("hello"); // 在str后追加一个字符"hello"cout…

openwrt固件选择推荐一:kwrt

前言 本文将推荐第一个openwrt固件Kwrt&#xff0c;帮助openwrt新手用户快速构建自己固件。下篇会推荐第二个Openwrt优秀固件。 一.openwrt定制系统&#xff1a;Kwrt github项目地址&#xff1a;点击跳转 支持300设备 1.提供在线定制页面&#xff0c;定制预装软件 固件在…

如何在 Windows 台式机或笔记本电脑上恢复未保存的 Excel 文件

您的汗水很容易化为灰烬&#xff0c;如果您没有保存长时间编写的项目报告或电子表格&#xff0c;这可能会令人心碎。丢失 Windows PC 上未保存的 Excel 文件可能是导致这种情况的原因。但您不应该惊慌。仍然有机会恢复未保存的 Excel 文件。 在本指南中&#xff0c;我们将向您…

failed to load steamui.dll的多种处理方法,steamui.dll的作用

在使用Steam平台时&#xff0c;不少玩家可能会遇到“failed to load steamui.dll”这样令人头疼的错误提示。这个错误会阻碍Steam客户端的正常运行&#xff0c;影响我们享受游戏和Steam平台的各种服务。不过&#xff0c;不必过于担心&#xff0c;因为有多种方法可以尝试解决这个…

车位租赁系统的设计与实现

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;车位信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广…

3d gaussian splatting公式推导

1. 离散公式推导 nerf中连续的积分渲染公式是&#xff1a; 其中被遮挡率&#xff1a; 那么转换为离散公式后有&#xff1a; 其中&#xff0c;代表j时刻的时间差&#xff0c;将其带入渲染公式&#xff1a; 设透明度 则被遮挡率 有 而gaussian-splating的公式与ner…

CNN-LSTM预测 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络时间序列预测

CNN-LSTM预测 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络时间序列预测 目录 CNN-LSTM预测 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络时间序列预测预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 本次运行测试环境MATLAB2020b 提出一种包含卷积神经网络和长短…

windows11环境安装lua及luarocks(踩坑篇)

一、lua安装及下载 官方地址&#xff1a; Lua Binaries Download 从这里就有坑了&#xff0c;下载后先解压win64_bin.zip&#xff0c;之后解压lib&#xff0c;用lib中的文件替换win64的&#xff0c;并把include文件夹复制过去&#xff0c;之后复制并重命名lua54&#xff0c;方…

面试知识点总结篇四

一、计算机网络 概念&#xff1a;互连的、自治的计算机系统的集合组成&#xff1a;硬件、软件、协议。功能组成&#xff1a;通信子网&#xff08;物理层、数据链路层、网络层&#xff09;、资源子网&#xff08;会话层、表示层、应用层&#xff09;分别有广域网、城域网、局域…

2024年软考网络工程师中级题库

1【考生回忆版】以下不属于5G网络优点的是&#xff08;A) A.传输过程中消耗的资源少&#xff0c;对设备的电池更友好 B.支持大规模物联网&#xff0c;能够连接大量低功耗设备&#xff0c;提供更高效的管理 C.引入了网络切片技术&#xff0c;允许将物理网络划分为多个虚拟网络…

数据分析:Python语言网络图绘制

文章目录 介绍加载R包类别导入数据下载数据画图介绍 网络图是一种图形表示法,用于展示实体之间的关系。在不同的领域中,网络图有着不同的含义和用途:在生物学中,网络图可以用来表示生物分子之间的相互作用,如蛋白质相互作用网络。 加载R包 import pandas as pd import …

Docker 安装 Apache(图文教程)

Apache HTTP服务器(简称Apache)是一个开源的、跨平台的Web服务器软件,由Apache软件基金会开发和维护。Apache HTTP服务器是世界上最流行的Web服务器软件之一,被广泛用于互联网上的网站和应用程序。 一、拉取镜像 docker pull httpd:latest二、运行容器 Apache的默认端口是…