学习笔记-MYSQL 事务

目录

一、什么是事务?

二、事务的四个特征(ACID)【面试常考项】

原子性(Atomicity)

一致性(Consistency)

隔离性(Isolation)

持久性(Durability)

三、MYSQL操作事务

1. 查看是否开启自动提交

2. 设置事务自动提交

3. 手动提交

4. 开启一条事务

5. 回滚

四、事务的并发问题

1. 隔离级别

2. 脏读

1. 打开数据库

2. 切换窗口B的隔离级别

3. 演示脏读

4. 重新设置窗口B的隔离级别

5. 再次演示脏读

3. 不可重复读

1. 切换窗口B 的隔离级别

2. 那怎么解决不可重复读的问题呢?

3. 重新设置窗口的隔离级别

4. 再次演示不可重复读

4. 幻读

1. 演示幻读

五、不可重复读和幻读的区别


一、什么是事务?

事务是访问并可能更新数据库中数据的一个执行单元,这个单元是由一条或多条语句组成,单元里的语句是相互依赖的。

这个单元里的SQL语句一起向系统提交,提交后要么都执行成功,要么都失败。例如:执行到一条SQL语句发生了报错,那么这个单元里已经执行成功的SQL语句也需要回滚操作,也就是返回初始状态

二、事务的四个特征(ACID)【面试常考项】

原子性(Atomicity)

原子是物理当中一种不可分割最小的单位。事务的原子性指事务是一个不可分割的最小执行单位(执行数据库操作)

一致性(Consistency)

事务必须使数据库从一个一致状态变到另一个一致状态。意味着事务完成后,所有的数据都符合预定的规则和约束。例如:转账的例子,张三给李四转账 100 元,张三的账户减去 100 元,李四的账户加 100 元,一致性就是其他事务看到的是  张三没有给李四转账,钱没有变化,张三给李四转账,张三的账户减 100 ,李四的账户加 100,不会出现 张三的账户减了 100,李四的账户没有加。

隔离性(Isolation)

隔离性意味着多个并发事务之间互不影响。即使多个事务同时进行,每一个事务都感觉像是系统中唯一的事务。也就是说,一个事务在读取数据时,不会看到其他未提交事务的更改,这避免了脏读、不可重复读和幻读等问题。

持久性(Durability)

当一个事务成功提交,数据的修改是永久性的,也就是会把数据写到物理存储中保存下来

三、MYSQL操作事务

MYSQL默认是开启事务,且一条 SQL 语句就会生成一个事务去执行,这个事务是自动提交的

1. 查看是否开启自动提交

0 表示关闭了自动提交

1 表示开启了自动提交

SELECT @@autocommit

2. 设置事务自动提交

SET @@autocommit = 0 // 关闭自动提交事务
SET @@autocommit = 1 // 开启自动提交事务

3. 手动提交

commit        手动提交

4. 开启一条事务

5. 回滚

start  transaction;        单独开启一条事务rollback;        回滚操作

遇到报错后进行回滚

 这样数据不会被修改

四、事务的并发问题

为了避免事务的并发问题,数据库使用不同的事务隔离级别。

1. 隔离级别

在MySQL中,事务有4种隔离级别,分别为READ UNCOMMITTED(读未提交)、READ COMMITTED(读已提交)、REPEATABLE READ(可重复读)和SERIALIZABLE(串行化)。

隔离级别问题
READ UNCOMMITTED(读未提交)脏读
READ COMMITTED(读已提交)允许不可重复读
REPEATABLE READ(可重复读)允许幻读
SERIALIZABLE(串行化)串行化读,事务只能一个一个执行

例如,在“读已提交”(Read Committed)级别,一个事务只能读取已经提交的数据,这就防止了脏读的发生。

为了更直观的感受什么是脏读,不可重复读,幻读和串行化读,我们使用 CMD 命令打开两个窗口来进行演示

2. 脏读

事务A 读取了事务B还没有提交的数据,然后事务B 又进行了回滚操作,这时,事务A读取的数据就是脏数据。

1. 打开数据库

窗口A,窗口B 都连接数据库,然后切换你自己的数据库

2. 切换窗口B的隔离级别

MySQL默认隔离级别是REPEATABLE READ,该级别可以避免脏读。为了方便演示,把隔离级别修改为 READ UNCOMMITTED(读未提交)

// 查看隔离级别
SHOW VARIABLES LIKE 'transaction_isolation';
// 修改隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

 

3. 演示脏读

在窗口A 开启事务,修改张三的 money

注意:先不要提交事务

在窗口 B 查看信息

可以看到,在窗口B可以看到还未提交的数据

脏读演示好了,可以在窗口A 使用 roolback;命令回滚事务

那怎么解决脏读呢?使用 READ COMMITTED(读已提交)隔离级别可以避免脏读

4. 重新设置窗口B的隔离级别
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
Query OK, 0 rows affected (0.00 sec)mysql> SHOW VARIABLES LIKE 'transaction_isolation';
+-----------------------+----------------+
| Variable_name         | Value          |
+-----------------------+----------------+
| transaction_isolation | READ-COMMITTED |
+-----------------------+----------------+
1 row in set, 1 warning (0.00 sec)mysql>

5. 再次演示脏读

先在窗口B查询一下数据

mysql> select * from user;
+---------+-----------+----------+-------+
| user_id | user_name | user_pwd | money |
+---------+-----------+----------+-------+
|       1 | zhangsan  | 123      |   900 |
|       2 | lisi      | 123      |   200 |
+---------+-----------+----------+-------+
2 rows in set (0.00 sec)mysql>

在窗口 A 修改张三的 money

开启一个事务

mysql> rollback;
Query OK, 0 rows affected (0.01 sec)mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)mysql> update user set money = 1000 where user_id = 1;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from user;
+---------+-----------+----------+-------+
| user_id | user_name | user_pwd | money |
+---------+-----------+----------+-------+
|       1 | zhangsan  | 123      |  1000 |
|       2 | lisi      | 123      |   200 |
+---------+-----------+----------+-------+
2 rows in set (0.00 sec)mysql>

然后在窗口 B 可以看到,没有查询到 窗口 A 未提交的数据

说明 READ COMMITTED(读已提交)隔离级别可以解决脏读的问题

演示完毕,使用 rollback;命令回滚

mysql> select * from user;
+---------+-----------+----------+-------+
| user_id | user_name | user_pwd | money |
+---------+-----------+----------+-------+
|       1 | zhangsan  | 123      |   900 |
|       2 | lisi      | 123      |   200 |
+---------+-----------+----------+-------+
2 rows in set (0.00 sec)mysql>

3. 不可重复读

不可重复读是指在访问数据库的数据时,一个事务对同一个数据进行多次读取时,期间其他事务可能对数据进行了更新,所以读取的结果可能不同

这通常发生在事务隔离级别为“读已提交”(Read Committed)时。

1. 切换窗口B 的隔离级别

切换 隔离级别为 READ COMMITTED(读已提交),然后开启事务,查询张三的信息

mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
Query OK, 0 rows affected (0.00 sec)mysql> SHOW VARIABLES LIKE 'transaction_isolation';
+-----------------------+----------------+
| Variable_name         | Value          |
+-----------------------+----------------+
| transaction_isolation | READ-COMMITTED |
+-----------------------+----------------+
1 row in set, 1 warning (0.00 sec)mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)mysql> select * from user where user_id = 1;
+---------+-----------+----------+-------+
| user_id | user_name | user_pwd | money |
+---------+-----------+----------+-------+
|       1 | zhangsan  | 123      |   900 |
+---------+-----------+----------+-------+
1 row in set (0.00 sec)mysql>

在窗口A更新张三的信息

mysql> update user set money = 2000 where user_id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from user;
+---------+-----------+----------+-------+
| user_id | user_name | user_pwd | money |
+---------+-----------+----------+-------+
|       1 | zhangsan  | 123      |  2000 |
|       2 | lisi      | 123      |   200 |
+---------+-----------+----------+-------+
2 rows in set (0.00 sec)mysql>

在窗口B再次查询张三的信息

可以看到,在窗口 B 一个事务的两次查询的结果不一样,其实不可重复读并不算错误,但在有些情况下却不符合实际需求。

不可重复读演示完毕,使用 COMMIT 手动提交事务

mysql> select * from user where user_id = 1;
+---------+-----------+----------+-------+
| user_id | user_name | user_pwd | money |
+---------+-----------+----------+-------+
|       1 | zhangsan  | 123      |  2000 |
+---------+-----------+----------+-------+
1 row in set (0.00 sec)mysql> commit;
Query OK, 0 rows affected (0.00 sec)

2. 那怎么解决不可重复读的问题呢?

为了避免不可重复读,可以使用更高一级的事务隔离级别“可重复读”(Repeatable Read)。

在该级别下,一旦事务开始,它会为所有读取操作创建一个快照,这个快照包含了事务开始时的数据状态。

这样一来,即使有其他事务修改并提交了数据,当前事务内的读取操作总是基于开始时的快照,从而保证了数据的重复读取结果一致。

3. 重新设置窗口的隔离级别

修改窗口B的隔离级别为 REPEATABLE READ(可重复读)

mysql> SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Query OK, 0 rows affected (0.00 sec)mysql> SHOW VARIABLES LIKE 'transaction_isolation';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set, 1 warning (0.00 sec)mysql>

4. 再次演示不可重复读

在窗口B开启一个事务,查询张三的信息

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)mysql> select * from user where user_id = 1;
+---------+-----------+----------+-------+
| user_id | user_name | user_pwd | money |
+---------+-----------+----------+-------+
|       1 | zhangsan  | 123      |  2000 |
+---------+-----------+----------+-------+
1 row in set (0.00 sec)mysql>

在窗口A 修改张三的信息

mysql> update user set money = 3000 where user_id = 1;
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from user;
+---------+-----------+----------+-------+
| user_id | user_name | user_pwd | money |
+---------+-----------+----------+-------+
|       1 | zhangsan  | 123      |  3000 |
|       2 | lisi      | 123      |   200 |
+---------+-----------+----------+-------+
2 rows in set (0.00 sec)mysql>

 再次在窗口 B 查询张三的信息

可以看到,在可重复读的隔离级别下,其他事务对数据的更新不会影响这个事务的读取

演示完毕,使用 commit; 提交事务

mysql> select * from user where user_id = 1;
+---------+-----------+----------+-------+
| user_id | user_name | user_pwd | money |
+---------+-----------+----------+-------+
|       1 | zhangsan  | 123      |  2000 |
+---------+-----------+----------+-------+
1 row in set (0.00 sec)mysql>

4. 幻读

指同一个事务两次读取的数据不一致,对于这个事务来说,突然多出几条数据,就好像出现了幻觉。 这是其他事务对数据进行了插入或者删除导致的

注意:可重复读 隔离级别也会发生幻读这个问题,但是一般在多个事务并发的时候才可能会出现,这里为了方便演示,设置 隔离级别为 读已提交

1. 演示幻读

在窗口 B 开启一个事务,查询数据表的所有数据

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)mysql> select * from user;
+---------+-----------+----------+-------+
| user_id | user_name | user_pwd | money |
+---------+-----------+----------+-------+
|       1 | zhangsan  | 123      |  3000 |
|       2 | lisi      | 123      |   200 |
+---------+-----------+----------+-------+
2 rows in set (0.00 sec)mysql>

在窗口A 新增一条数据

mysql> insert into user value('3','test','123',1000);
Query OK, 1 row affected (0.02 sec)mysql> select * from user;
+---------+-----------+----------+-------+
| user_id | user_name | user_pwd | money |
+---------+-----------+----------+-------+
|       1 | zhangsan  | 123      |  3000 |
|       2 | lisi      | 123      |   200 |
|       3 | test      | 123      |  1000 |
+---------+-----------+----------+-------+
3 rows in set (0.00 sec)mysql>

在窗口B 再次查询表中所有数据

可以看到,表中也显示了新增的数据

mysql> select * from user;
+---------+-----------+----------+-------+
| user_id | user_name | user_pwd | money |
+---------+-----------+----------+-------+
|       1 | zhangsan  | 123      |  3000 |
|       2 | lisi      | 123      |   200 |
|       3 | test      | 123      |  1000 |
+---------+-----------+----------+-------+
3 rows in set (0.00 sec)mysql>

五、不可重复读和幻读的区别

不可重复读和幻读的本质上是一样的,两次读取到的数据不一致,但是 不可重复读 是两次读取的同一条记录的结果不一致,幻读是两次读取表中的记录数量不一致

不可重复读重点在于 UPDATE 和 DELETE,而幻读的重点在于 INSERT

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

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

相关文章

Linux-理解shell

文章目录 5. 理解shell5.1 shell的类型5.2 交互shell和系统默认shell5.3 安装zsh shell程序5.4 shell的父子关系5.5 命令列表5.6 命令分组5.7 使用命令分组创建子shell5.8 子shell用法5.9 shell的非内建命令和内建命令5.9.1 非内建命令5.9.2 内建命令5.9.3 history和alias命令介…

AI9-文本识别

本章主要介绍文本识别算法的理论知识,包括背景介绍、算法分类和部分经典论文思路。 通过本章的学习,你可以掌握: 1. 文本识别的目标 2. 文本识别算法的分类 3. 各类算法的典型思想 1 背景介绍 文本识别是OCR(Optical Character Recognition)的一个子任务,其任务为识别一个…

基于 Redis 的分布式信号量 Spring Boot 集成 Redisson 使用 Semaphore 控制并发访问数量

目录 前言 pom yml Controller 演示 注意 前言 工作中开发过一个服务,这里记作A服务,主要功能是配置,部署以及调用云函数。其中配置云函数的功能里,有一个配置项是并发数,意思是同一时间最多能有多少个请求调用…

【MATLAB源码】数学建模基础教程(2)--层次分析法(评价类算法)

系列文章目录在最后面,各位同仁感兴趣可以看看! 层次分析法 引言一、层次分析法的特点二、模型的建立求解过程 (1)问题的提出:实际问题的转化(2)建立层次结构模型(3)构造判断(成对比较)矩阵(4)一致性检验:三、层次分析法的优点与…

Codeforces Round 871 (Div. 4)(A~H)

比赛链接 Dashboard - Codeforces Round 871 (Div. 4) - Codeforces A. Love Story 找到与codeforces 有多少个不同的字符。 #include<bits/stdc.h> #define int long long #define TEST int T; cin >> T; while (T--) #define ios ios::sync_with_stdio(fals…

前端常用的性能优化方案

目录 性能分析工具lighthouseWebpack Bundle分析 开发阶段按需引入路由懒加载 打包阶段打包配置减少包体积配置压缩分包 资源预加载/预请求 部署阶段开启http2静态资源缓存gzip压缩 性能优化主要在三个阶段进行&#xff1a;开发阶段、开发结束后的打包阶段、项目部署上线阶段 首…

提升生产效率:APS高级计划排程系统在车间工序级排程的革命性应用

在制造业的数字化转型浪潮中&#xff0c;APS高级计划排程系统以凭借自身卓越的排程运算能力和应用灵活性&#xff0c;已经成为中大型制造业提升生产效率的关键工具。APS系统的介入&#xff0c;打通了传统ERP和MES等各类业务系统运营平台&#xff0c;并且通过产能均衡规划&#…

为什么我3d模型选择面选不到?---模大狮模型网

在展览3D模型设计行业中&#xff0c;设计师常常面临诸多技术挑战&#xff0c;其中之一是在模型编辑过程中遇到选择面的困难。这不仅影响了设计工作效率&#xff0c;还可能影响最终作品的质量和展示效果。本文将探讨在3D模型设计中为何会遇到“为什么我3D模型选择面选不到?”这…

【MySQL进阶篇】管理

1、系统数据库 MySQL数据库安装完成之后&#xff0c;自带以下四个数据库&#xff0c;具体作用如下&#xff1a; 数据库含义mysql存储MySQL服务器正常运行所需要的各种信息&#xff08;时区、主从、用户、权限等&#xff09;information_schema提供了访问数据库元数据的各种表…

实战OpenCV之环境安装与配置

OpenCV是什么 OpenCV&#xff0c;英文全称为Open Source Computer Vision Library&#xff0c;是一个开源的计算机视觉和机器学习软件库。它设计用于提供一系列功能强大的算法&#xff0c;以帮助开发者处理图像和视频数据&#xff0c;实现各种视觉任务&#xff0c;包括&#xf…

.NET内网实战:模拟Installer关闭Defender

01基本介绍 02编码实现 原理上通过Windows API函数将当前进程的权限提升至TrustedInstaller&#xff0c;从而实现了对Windows Defender服务的控制。通常可以利用Windows API中的OpenSCManager、OpenProcessToken、ImpersonateLoggedOnUser以及ControlService等函数协同工作&am…

从干涉实验、化学反应到晶体管的科学之旅 - 《量子宇宙》读后感

在《量子宇宙》这本书中&#xff0c;作者没有讲述历史和发现的故事&#xff0c;而是从头到尾用公式推导来展示宇宙和现代物理学的壮美。 量子理论处理的是概率&#xff0c;而不是确定性。大自然在某些方面本质上就是由或然率支配的。计算粒子出现的概率是我们能做到的极限。 …

渗透小游戏,各个关卡的渗透实例---步骤简单(含代码)

文章目录 Less-1Less-2Less-5updatexml报错注入&#xff1a; Less-6Less-7Less-8Less-9Less-11Less-13Less-15 Less-1 首先&#xff0c;可以看见该界面&#xff0c;该关卡主要是SQL注入&#xff0c;由于对用户的输入没有做过滤&#xff0c;使查询语句进入到了数据库中&#xff…

springboot电影院线上购票系统-计算机毕业设计源码68220

目录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2系统分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统流程分析 2.2.1 添加信息流程 2.2.2 修改信息流程 2.2.3 删除信息流程 2.3 系统功能分析 2.…

synchronized 与 Lock 的区别

synchronized 与 Lock 的区别 1、相同点2、不同点2.1 精确性与灵活性2.2 性能2.3 使用便利性 3、示例3.1 synchronized 示例3.2 Lock 示例 4、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java多线程编程中&#xff0c;synchroniz…

智能家居沙盘系统-智慧家居沙盘系统

智能家居和物联网技术是当前科技领域的热门话题&#xff0c;随着各类智能家居产品的不断推出&#xff0c;智能家居市场也逐渐呈现出蓬勃发展的态势。智能家居快速发展&#xff0c;而物联网相关人才供应远远不足。高校开展智能家居工程及设计人才教育培养具有重大意义。 基本介绍…

【stm32】EXTI外部中断

EXTI外部中断 1、中断系统2、中断执行流程3、STM32中断4、NVIC基本结构5、NVIC优先级分组6、EXTI简介&#xff08;引脚电平变化&#xff0c;申请中断&#xff09;7、EXTI基本结构8、AFIO复用IO口9、EXTI框图10、旋转编码器简介11、程序设计&#xff1a;1.使用对射式红外传感器触…

vue3实现商品图片放大镜效果(芋道源码yudao-cloud 二开笔记)

今天开发一个防某商城的商品图片放大镜&#xff0c;鼠标移动到图片位置时&#xff0c;右侧出现一个已放大的图片效果。 示例如下&#xff1a; 下图的图片的放大效果和小图的切换封装成了组件PicShow.vue&#xff0c;可根据需求自行修改&#xff0c;如下&#xff1a; 第一步&…

Html5总结

前端学习 html决定页面的结构css决定页面的样式js决定页面的行为 Html5 1.文本格式化标签&#xff08;熟记&#xff09; 你在网页中&#xff0c;有时需要为文字设置粗体、斜体或下划线效果&#xff0c;这时就需要用到HTML中的文本格式化标记 2.标签属性 例如&#xff1a; …

算法 —— 位运算

目录 位运算常用结论 位运算例题 位1的个数 比特位计算 汉明距离 只出现一次的数字 判定字符是否唯一 丢失的数字 两整数之和 消失的两个数字 进制转换 位运算常用结论 想详细了解位运算的内容可以阅读我的这篇博客&#xff1a;应该背下的位运算 以下我只介绍一些位…