【MySQL】16.事务管理(重点) -- 2

1. 事务隔离级别

如何理解隔离性1

  • MySQL服务可能会同时被多个客户端进程(线程)访问,访问的方式以事务方式进行
  • 一个事务可能由多条SQL构成,也就意味着,任何一个事务,都有执行前,执行中,执行后的阶段。而所谓的原子性,其实就是让用户层,要么看到执行前,要么看到执行后。执行中出现问题,可以随时回滚。所以单个事务,对用户表现出来的特性,就是原子性。
  • 但,毕竟所有事务都要有个执行过程,那么在多个事务各自执行多个SQL的时候,就还是有可能会出现互相影响的情况。比如:多个事务同时访问同一张表,甚至同一行数据。
  • 就如同你妈妈给你说:你要么别学,要学就学到最好。至于你怎么学,中间有什么困难,你妈妈不关心。那么你的学习,对你妈妈来讲,就是原子的。那么你学习过程中,很容易受别人干扰,此时,就需要将你的学习隔离开,保证你的学习环境是健康的。
  • 数据库中,为了保证事务执行过程中尽量不受干扰,就有了一个重要特征:隔离性
  • 数据库中,允许事务受不同程度的干扰,就有了一种重要特征:隔离级别

2. 隔离级别

  • 读未提交【Read Uncommitted】: 在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。(实际生产中不可能使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多并发问题,如脏读,幻读,不可重复读等,我们上面为了做实验方便,用的就是这个隔离性。
  • 读提交【Read Committed】 :该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离 级别会引起不可重复读,即一个事务执行时,如果多次select, 可能得到不同的结果。
  • 可重复读【Repeatable Read】: 这是 MySQL 默认的隔离级别,它确保同一个事务,在执行中,多次读取操作数据时,会看到同样的数据行。但是会有幻读问题。
  • 串行化【Serializable】: 这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决了幻读的问题。它在每个读的数据行上面加上共享锁,。但是可能会导致超时和锁竞争 (这种隔离级别太极端,实际生产基本不使用)

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

3. 查看与设置隔离性

-- 查看
mysql> SELECT @@global.tx_isolation; --查看全局隔级别
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
|       REPEATABLE-READ |
+-----------------------+
1 row in set, 1 warning (0.00 sec)

mysql> SELECT @@session.tx_isolation; --查看会话(当前)全局隔级别
+------------------------+
| @@session.tx_isolation |
+------------------------+
|        REPEATABLE-READ |
+------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> SELECT @@tx_isolation; --默认同上
+-----------------+
|  @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set, 1 warning (0.00 sec)
-- 设置
-- 设置当前会话 or 全局隔离级别语法
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL
{READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
-- 设置当前会话隔离性,另起一个会话,看不多,只影响当前会话
mysql> set session transaction isolation level serializable; -- 串行化
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@global.tx_isolation; --全局隔离性还是RR
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
|       REPEATABLE-READ |
+-----------------------+
1 row in set, 1 warning (0.00 sec)

mysql> SELECT @@session.tx_isolation; --会话隔离性成为串行化
+------------------------+
| @@session.tx_isolation |
+------------------------+
|           SERIALIZABLE |
+------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> SELECT @@tx_isolation; --同上
+----------------+
| @@tx_isolation |
+----------------+
|   SERIALIZABLE |
+----------------+
1 row in set, 1 warning (0.00 sec)

--设置全局隔离性,另起一个会话,会被影响
mysql> set global transaction isolation level READ UNCOMMITTED;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
|      READ-UNCOMMITTED |
+-----------------------+
1 row in set, 1 warning (0.00 sec)

mysql> SELECT @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
|       READ-UNCOMMITTED |
+------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> SELECT @@tx_isolation;
+------------------+
|   @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set, 1 warning (0.00 sec)

-- 注意,如果没有现象,关闭mysql客户端,重新连接。

3.1 读未提交【Read Uncommitted】

--几乎没有加锁,虽然效率高,但是问题太多,严重不建议采用
--终端A
-- 设置隔离级别为 读未提交
mysql> set global transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)

--重启客户端
mysql> select @@tx_isolation;
+------------------+
|   @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set, 1 warning (0.00 sec)

mysql> select * from account;
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |   100.00 |
|  2 |    李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

mysql> begin; --开启事务
Query OK, 0 rows affected (0.00 sec)

mysql> update account set blance=123.0 where id=1; --更新指定行
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0
--没有commit哦!!!
--终端B
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from account;
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |   123.00 | --读到终端A更新但是未commit的数据[insert,delete同样]
|  2 |    李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)
-- 一个事务在执行中,读到另一个执行中事务的更新(或其他操作)但是未commit的数据,这种现象叫做脏读(dirty read)

3.2 读提交【Read Committed】 — 又名不可重复读

-- 终端A
mysql> set global transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)

--重启客户端
mysql> select * from account; --查看当前数据
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |   123.00 | 
|  2 |    李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

mysql> begin; --手动开启事务,同步的开始终端B事务
Query OK, 0 rows affected (0.00 sec)

mysql> update account set blance=321.0 where id=1; --更新张三数据
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

--切换终端到终端B,查看数据。

mysql> commit; --commit提交!
Query OK, 0 rows affected (0.01 sec)

--切换终端到终端B,再次查看数据。
--终端B
mysql> begin; --手动开启事务,和终端A一前一后
Query OK, 0 rows affected (0.00 sec)

mysql> select * from account; --终端A commit之前,查看不到
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |   123.00 | --老的值
|  2 |    李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

--终端A commit之后,看到了!
--but,此时还在当前事务中,并未commit,那么就造成了,同一个事务内,同样的读取,在不同的时间段
(依旧还在事务操作中!),读取到了不同的值,这种现象叫做不可重复读(non reapeatable read)!!
(这个是问题吗??)
mysql> select *from account;
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |   321.00 | --新的值
|  2 |    李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

3.3 可重复读【Repeatable Read】

--终端A
mysql> set global transaction isolation level repeatable read; --设置全局隔离级别RR
Query OK, 0 rows affected (0.01 sec)

--关闭终端重启

mysql> select @@tx_isolation;
+-----------------+
|  @@tx_isolation |
+-----------------+
| REPEATABLE-READ | --隔离级别RR
+-----------------+
1 row in set, 1 warning (0.00 sec)

mysql> select *from account; --查看当前数据
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |   321.00 | 
|  2 |    李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

mysql> begin; --开启事务,同步的,终端B也开始事务
Query OK, 0 rows affected (0.00 sec)

mysql> update account set blance=4321.0 where id=1; --更新数据
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

--切换到终端B,查看另一个事务是否能看到
--终端B
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from account; --终端A中事务 commit之前,查看当前表中数据,数据未更新
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |   321.00 | 
|  2 |    李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

mysql> select * from account; --终端A中事务 commit 之后,查看当前表中数据,数据未更新
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |  321.00 | 
|  2 |    李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

--可以看到,在终端B中,事务无论什么时候进行查找,看到的结果都是一致的,这叫做可重复读!

mysql> commit; --结束事务
Query OK, 0 rows affected (0.00 sec)

mysql> select * from account; --再次查看,看到最新的更新数据
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |  4321.00 | 
|  2 |    李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

实验2:

--如果将上面的终端A中的update操作,改成insert操作,会有什么问题??
--终端A

mysql> select *from account;
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |   321.00 | 
|  2 |    李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

mysql> begin; --开启事务,终端B同步开启
Query OK, 0 rows affected (0.00 sec)

mysql> insert into account (id,name,blance) values(3, '王五', 5432.0);
Query OK, 1 row affected (0.00 sec)

--切换到终端B,查看另一个事务是否能看到

mysql> commit; --提交事务
Query OK, 0 rows affected (0.00 sec)

--切换终端到终端B,查看数据。
mysql> select * from account;
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |  4321.00 | 
|  2 |    李四 | 10000.00 |
|  3 |    王五 |  5432.00 |
+----+--------+----------+
3 rows in set (0.00 sec)
--终端B
mysql> begin; --开启事务
Query OK, 0 rows affected (0.00 sec)

mysql> select * from account; --终端A commit前 查看
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |   321.00 | 
|  2 |    李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)
mysql> select * from account; --终端A commit后 查看
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |   321.00 | 
|  2 |    李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

在这里插入图片描述

mysql> commit; --结束事务
Query OK, 0 rows affected (0.00 sec)

mysql> select * from account; --看到更新
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |  4321.00 | 
|  2 |    李四 | 10000.00 |
|  3 |    王五 |  5432.00 |
+----+--------+----------+
3 rows in set (0.00 sec)

3.4 串行化【serializable】

-- 对所有操作全部加锁,进行串行化,不会有问题,但是只要串行化,效率很低,几乎完全不会被采用
-- 终端A
mysql> set global transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)

mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
|   SERIALIZABLE |
+----------------+
1 row in set, 1 warning (0.00 sec)

mysql> begin; --开启事务,终端B同步开启
Query OK, 0 rows affected (0.00 sec)

mysql> select * from account; --两个读取不会串行化,共享锁
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |  4321.00 | 
|  2 |    李四 | 10000.00 |
|  3 |    王五 |  5432.00 |
+----+--------+----------+
3 rows in set (0.00 sec)

mysql> update account set blance=1.00 where id=1; --终端A中有更新或者其他操作,会阻塞。直到终端B事务提交。
Query OK, 1 row affected (18.19 sec)
Rows matched: 1 Changed: 1 Warnings: 0
--终端B
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from account; --两个读取不会串行化
+----+--------+----------+
| id |   name |   blance |
+----+--------+----------+
|  1 |    张三 |  4321.00 | 
|  2 |    李四 | 10000.00 |
|  3 |    王五 |  5432.00 |
+----+--------+----------+
3 rows in set (0.00 sec)

mysql> commit; --提交之后,终端A中的update才会提交。
Query OK, 0 rows affected (0.00 sec)

在这里插入图片描述

3.5 总结:

  • 其中隔离级别越严格,安全性越高,但数据库的并发性能也就越低,往往需要在两者之间找一个平衡点。
  • 不可重复读的重点是修改和删除:同样的条件, 你读取过的数据,再次读取出来发现值不一样了
  • 幻读的重点在于新增:同样的条件, 第1次和第2次读出来的记录数不一样
  • 说明: mysql 默认的隔离级别是可重复读,一般情况下不要修改
  • 上面的例子可以看出,事务也有长短事务这样的概念。事务间互相影响,指的是事务在并行执行的时候,即都没有commit的时候,影响会比较大。

在这里插入图片描述
一致性(Consistency)

  • 事务执行的结果,必须使数据库从一个一致性状态,变到另一个一致性状态。当数据库只包含事务成功提交的结果时,数据库处于一致性状态。如果系统运行发生中断,某个事务尚未完成而被迫中断,而改未完成的事务对数据库所做的修改已被写入数据库,此时数据库就处于一种不正确(不一致)的状态。因此一致性是通过原子性来保证的。
  • 其实一致性和用户的业务逻辑强相关,一般MySQL提供技术支持,但是一致性还是要用户业务逻辑做支撑,也就是,一致性,是由用户决定的。
  • 而技术上,通过AID保证C

推荐阅读

https://www.jianshu.com/p/398d788e1083
https://tech.meituan.com/2014/08/20/innodb-lock.html
https://www.cnblogs.com/aspirant/p/9177978.html

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Echarts的超市销售可视化分析系统(数据+程序+论文)

本论文旨在研究Python技术和ECharts可视化技术在超市销售数据分析系统中的应用。本系统通过对超市销售数据进行分析和可视化展示,帮助决策层更好地了解销售情况和趋势,进而做出更有针对性的决策。本系统主要包括数据处理、数据可视化和系统测试三个模块。…

基于随机森林与LSTM神经网络的住宅用电比较分析及预测 代码+论文 完整毕设

摘要 本文旨在探讨基于随机森林(Random Forest)与长短期记忆神经网络(Long Short-Term Memory, LSTM)的住宅用电比较分析及预测方法。随机森林是一种集成学习方法,通过构建多个决策树进行预测,具有较强的鲁…

FL Studio21.2.3.4004音乐制作及里程碑及功能介绍

**FL Studio 21.2.3.4004:音乐制作的新里程碑** 随着数字音乐制作技术的不断发展,音乐制作软件也在不断迭代升级。今天,我们将聚焦于一款广受欢迎的音乐制作软件——FL Studio 21.2.3.4004,探讨它如何成为音乐制作领域的新里程碑…

【技巧】如何设置和解除PDF的“打开密码”?

在工作中,我们经常会接触到PDF文件,对于重要的文件,往往还会设置密码保护,那PDF的“打开密码”如何设置和解除呢?下面小编分享两种方法,一起来看看吧! 方法一:使用PDF编辑器 大部分…

基于连续深度编解码器网络的医学图像鲁棒边界分割

基于连续深度编解码器网络的医学图像鲁棒边界分割 摘要引言相关工作方法-----III. PROPOSED METHOD Robust_Boundary_Segmentation_in_Medical_Images_Using_a_Consecutive_Deep_Encoder-Decoder_Network 摘要 图像分割通常用于定位目标和边界。它在许多临床应用中是必不可少的…

一步一步搭建,功能最全的权限管理系统之动态路由菜单

一、前言 这是一篇搭建权限管理系统的系列文章。 随着网络的发展,信息安全对应任何企业来说都越发的重要,而本系列文章将和大家一起一步一步搭建一个全新的权限管理系统。 说明:由于搭建一个全新的项目过于繁琐,所有作者将挑选核心…

1320亿参数,性能超LLaMA2、Grok-1!开源大模型DBRX

3月28日,著名数据和AI平台Databricks在官网正式开源大模型——DBRX。 DBRX是一个专家混合模型(MoE)有1320亿参数,能生成文本/代码、数学推理等,有基础和微调两种模型。 根据DBRX在MMLU、HumanEval和 GSM8K公布的测试…

蓝牙双模音频模块支持串口AT指令控制介绍

目录 一、BT401蓝牙音频模块简介 蓝牙音频模块支持串口AT指令控制介绍,这里推荐BT401蓝牙模块,功能简介如下: BT401模块是一款支持蓝牙、U盘、TF卡播放的5合1的解决方案。模组的亮点在支持无损音乐的播放,以及简单明了的串口控制…

婴儿专用洗衣机哪个牌子好?四大爆款婴儿洗衣机合集安利

婴儿的衣物需要特别的护理,因为婴儿的皮肤非常娇嫩,需要一个无菌,没有刺激性的洗涤环境,于是婴儿洗衣机应运而生。如果你非常注重婴儿衣物的卫生问题,那么婴儿洗衣机则是非常理想的选择。毕竟,在婴儿吃奶或…

文件上传失败原因分析与解决

图片文件上传失败 问题描述&#xff1a;在前端开发时&#xff0c;需要通过表单元素上传图片或其他文本&#xff0c;但是上传不成功&#xff0c;后端接口也没问题 html <!--onChange用来绑定数据 handleUpload用来提交数据--><form onSubmit{handleUpload}><…

Cadence HDL导出BOM并将网页数据导入Excle

【仅供个人学习记录&#xff0c;勿作他用。转载注明出处】 1. 如何导出BOM&#xff1f; 【说明】将后缀改为网页“html”&#xff0c;并勾选下面的网页。 之后就会跳出浏览器中你的BOM表就会显示。 2. 将网页BOM导入Excle&#xff1f; 不想要这个 想要这个&#xff01;&…

vscode配置c/c++调试环境

本文记录win平台使用vscode远程连接ubuntu server服务器下&#xff0c;如何配置c/c调试环境。 过程 1. 服务器配置编译环境 这里的前置条件是vscode已经能够连接到服务器&#xff0c;第一步安装编译构建套件&#xff08;gcc、g、make、链接器等&#xff09;和调试器&#xf…

眼底 Fundus、OCT 图竞赛分析

眼底 Fundus、OCT 图竞赛分析 眼底 Fundus 图竞赛&#xff08;8分类&#xff09;算法设计ResNet简介双路ResNet2d网络的工作原理应用数据预处理训练和验证 代码分析 眼底 OCT 图&#xff08;8分类&#xff09;代码分析眼底图分类最新研究 MuReD 视网膜疾病 &#xff08;20分类&…

必须进行App测试吗?专业第三方软件测试机构分享移动App测试好处

在这个移动互联网时代&#xff0c;移动应用程序App已经成为人们生活中必不可少的一部分。然而&#xff0c;随着市场上App数量不断增加&#xff0c;质量的好坏成为用户选择的重要标准。因此&#xff0c;在发布之前&#xff0c;一个必不可少的步骤就是对移动App进行软件测试。 移…

FlashDB移植到STM32F103内部flash,FatFs、FlashDB 、EasyFlash的不同

文章目录 一、前言二、FatFs、FlashDB 、EasyFlash 区别2.1 FlashDB2.2 EasyFlash2.3 FATFS 三、FatFs、FlashDB、EasyFlash 区使用环境3.1 FlashDB:3.2 FATFS:3.3 EasyFlash: 四、FlashDB移植4.1 项目 GITEE 地址4.2 项目目录4.3 移植的目录树4.4 MDK keil 添加文件4.5 添加头…

Python---Numpy学习

首先&#xff0c;先来认识一下Numpy数组对象&#xff0c;以及如何创建它 import numpy as np# 1.认识数组对象 # 指定取值范围和跨度创建数组对象 # 创建一个3行4列的数组 data np.arange(12).reshape(3, 4)print(data)print(type(data))# 维度 print(data.shape)# 维度的个数…

架构师之路--docker命令实践整理

安装docker sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine sudo yum install -y yum-utils sudo yum-config-manager --add-repo http://mirrors.aliyun.com/…

谭浩强第五版C语言课后习题(编程题)+答案

谭浩强第五版作为初学C语言必读的一本教材&#xff0c;课后习题具有非常大的参考价值&#xff0c;也是很多高校期末考试或者考研的重要参考。在这里我整理了一部分个人认为比较重要的编程题&#xff0c;供大家作参考 1.输入两个数&#xff0c;求他们的最大公约数和最小公倍数&…

Vector授权狗驱动安装方法

安装好主体软件后&#xff0c;建议先安装最新官方正版驱动&#xff1a;Vector Driver Setup。然后再复制补丁到C盘指定位置&#xff0c;替换原文件。如果你之前已安装老版本的驱动&#xff0c;则建议先卸载老版本的驱动&#xff0c;主体软件不需要卸载。卸载建议用原来安装时用…

关于柔性阵列(/三维阵列)波束形成的仿真实践以及稳健波束形成的思考(1)

说明 关于波束形成&#xff0c;我之前写过几篇相关的博文&#xff0c;如参考资料[1]、[2]、[3]。除去在博文[2]中有讨论过阵元相对位置关系对波束形成的影响&#xff1a;“如何基于遗传算法优化阵元相对位置关系以压低旁瓣峰值”以外&#xff0c;似乎我认知里的天线阵列&#x…
最新文章