【MySQL】 -- 事务

如果对表中的数据进行CRUD操作时,不加控制,会带来一些问题。
比如下面这种场景:

image.png
有一个tickets表,这个数据库被两个客户端机器A和B用时连接对此表进行操作。客户端A检查tickets表中还有一张票的时候,将票出售了,而火车票的总数是一个固定值,客户端A此时还没有来得及更新数据库
这时客户端B检查了票数,发现还有一张,又卖了一次票。这种情况,就出现了同一张票被卖了两次的场景。

这就是在进行CRUD时,不加控制带来的问题。
只要当进进行CRUD时满足以下属性,才能解决上面的问题:

  1. 买票的过程得是原子的
  2. 买票互相应该不能影响
  3. 买完票应该要永久有效
  4. 买前,和买后都要是确定的状态

而MySQL的事务机制,就能够有效的解决此问题。

1. MySQL事务

事务就是一组DML语句组成,这些语句在逻辑上存在相关性,这一组DML语句要么全部成功,要么全部失败,是一个整体。

MySQL提供一种机制,保证我们达到这样的效果。事务还规定不同的客户端看到的数据是不相同的。

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

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

所以一个完整的事务,不仅仅是简单的DML组合而成,还要满足以下4个特点:

  • 原子性(Atomicity) :事务中的所有操作要么全部完成,要么全部不完成。
  • 一致性(Consistency) :事务执行前后,数据库的状态必须保持一致。
  • 隔离性(Isolation) :一个事务的执行不能被其他事务干扰。
  • 持久性(Durability) :一旦事务提交,其对数据库的修改应该永久保存。

以上 四个属性可以简称为ACID

所以事务就是一条或者多条SQL语句组成并包含ACID

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

1.1 MySQL事务支持的版本

MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务, MyISAM不支持。
使用show engines可以查看。

image.png

1.2 事务的提交方式

事务的提交方式常见的有两种

  • 自动提交
  • 手动提交

使用show variables like 'autocommit';可以查看事务提交的方式。

image.png
ON表示为自动提交。

可以通过set autocommit来更改自动提交模式。值为0,表示禁止自动提交。

image.png
值为1,表示开启自动提交。

image.png

1.3 事务常见的操作方式

为了方便演示,这里创建一张测试表account。

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;

这里还需要不同的主机连接到同一个数据库中,我使用本地和服务器的mysql客户端进行连接。
使用SHOW PROCESSLIST;可以查看数据库的连接情况。

image.png
除此之外还需要将mysql的默认隔离级别设置成读未提交。
set global transaction isolation level READ UNCOMMITTED;
使用此命令设置完成后,重启客户端进行连接隔离级别才会生效。

image.png

先查看事务是否是自动提交,使用show variables like 'autocommit';命令进行查看。

image.png
ON表示开启自动提交。以下提交的方式都是自动提交的。

1.3.1 开始一个事务

开始一个事务,可以使用being或者start transaction

image.png

1.3.2 创建一个保存点

使用savepoint 保存点名进行设置一个保存点

image.png

1.3.3 回滚到保存点

使用rollback to 保存点名即可回滚到指定的保存点中。
使用rollback可以直接回滚到最开始。

image.png

使用示例-事务的开始和回滚

image.png
此时另一个客户端在查询时,也可以查询到。做到了一致性。

image.png
这样两个客户端同时操作一个表的时候,就可以有效的解决冲突了。

事务使用示例-自动回滚

当提交方式为自动提交的时候,客户端崩溃的后,MySQL会自动回滚。(隔离级别设置为提交未读)

在客户端A中使用事务进行插入。如下。

image.png
插入一条记录后,从另一个客户端B中就可以查询到,如下:
image.png

此时,客户端A崩溃了,那么MySQL就会自动回滚。

image.png
自动回滚后,在客户端B中就无法查询到插入的这条记录了。

image.png

事务使用示例-提交后,客户端崩溃后,MySQL的数据不会在受到影响。(持久化特性)

在客户端A事务中插入一条记录,然后手动提交,客户端A崩溃。
image.png
此时在另一个客户端B中进行查询,依然可以查询到。

image.png
事务做到了数据持久化,不会被影响。

事务使用示例-begin操作会自动更改提交方式,不会受MySQL是否自动提交影响

image.png

image.png

事务使用示例-单条 SQL 与事务的关系

单条SQL:

image.png
此时客户端B在进行查询的时候就无法查询到此记录。

image.png

事务:

image.png
此时客户端B在进行查询的时候依然可以查询到此记录。数据已经被持久化了。

image.png

1.4 总结

  • 只要输入begin或者start transaction,事务便必须要通过commit提交,才会持久化,与是 否设置set autocommit无关。
  • 事务可以手动回滚,同时,当操作异常,MySQL会自动回滚
  • 对于 InnoDB 每一条 SQL 语言都默认封装成事务,自动提交。(select有特殊情况,因为 MySQL 有 MVCC )

事务操作注意事项:

  • 如果没有设置保存点,也可以回滚,只能回滚到事务的开始。直接使用 rollback(前提是事务 还没有提交)。
  • 如果一个事务被提交了(commit),则不可以回退(rollback)
  • 可以选择回退到哪个保存点
  • InnoDB 支持事务, MyISAM 不支持事务
  • 开始事务可以使 start transaction 或者 beginbegin更简洁 推荐使用。

2. 事务隔离级别

  • MySQL服务可能会同时被多个客户端进程(线程)访问,访问的方式以事务的方式进行。
  • 一个事务可能由多条SQL语句构成,也就意味着任何一个事务,都有执行前、执行中和执行后三个阶段,而所谓的原子性就是让用户层要么看到执行前,要么看到执行后,执行中如果出现问题,可以随时进行回滚,所以单个事务对用户表现出来的特性就是原子性。
  • 但毕竟每个事务都有一个执行的过程,在多个事务各自执行自己的多条SQL时,仍然可能会出现互相影响的情况,比如多个事务同时访问同一张表,甚至是表中的同一条记录。
  • 数据库中,为了保证事务执行过程中尽量不受干扰,就有了一个重要特征:隔离性
  • 数据库中,允许事务受不同程度的干扰,就有了一种重要特征:隔离级别

数据库的隔离级别一共有以下四种。

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

2.1 查看隔离性

  • SELECT @@global.tx_isolation;:查看全局的隔离级别
    image.png
  • SELECT @@session.tx_isolation; 或者 SELECT @@tx_isolation;:查看当前会话的隔离级别
  • image.png

2.2 设置隔离级别

  • 设置当前会话 or 全局隔离级别语法:
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | Serializable}

比如设置当前会话隔离级别为Serializable。

image.png

设置全局隔离性的话,另起一个会话就会被影响。重启MySQL客户端生效

image.png

2.2.1 读未提交【Read Uncommitted】

该隔离级别,效率虽然很高,但是问题太多,严重不建议使用。
问题如下:
1、将事务的隔离级别设置为Read Uncommitted

image.png

2、在一个终端A中开启事务,然后插入一条记录。不进行提交。

image.png
3、在另一个终端中进行查询

image.png

这就是Read Uncommitted隔离级别做严重的问题,读到了未提交的数据。这种现象称之为脏读~

2.2.2 读提交【Read Committed】

按照命名来看,对比读未提交,读提交只读已提交的数据。但是这种隔离级别有新的问题。读到的值不同。问题如下:
1、将隔离级别设置为Read Committed

image.png

2、开启事务,不提交在另一个客户端进行查询

image.png
在另一个终端中读不到。

image.png

3、进行提交,在另一个终端再次读取。
终端A使用commit提交后,在终端B中就可以查到了。

image.png

到此,读提交解决了读未提交的问题。
但是,如果在终端A更新插入一条记录,不提交,终端B就能读到了。回到了读未提交的现象。

image.png

终端B还是读到了

image.png
这种现象叫做不可重复读,解决这个问题,又有了新的隔离级别。 可重复读【Repeatable Read】

2.2.3 可重复读【Repeatable Read】

这种隔离级别解决了读未提交和读提交的问题,但是又带来了幻读的问题。如下:
1、设置隔离级别为Repeatable Read

image.png

2、开启事务,插入记录

image.png

不提交,此时在另一个终端就无法进行查询到。解决读未提交的问题。

image.png
继续在终端A中插入一条记录

image.png

此时在终端中就能查询到了。

image.png
继续插入,不提交,另一个终端也无法查到。

同样的,在终端A中插入一条记录,并提交结束事务。

image.png
然后再终端B查询终端Acommit后的纪律。

image.png
但是,多次查询后,在终端B中无法查询到A commit到的记录。

这倒也没有什么影响,也符合可重复的特点。
但是,一般的数据库在可重复读情况的时候,无法屏蔽其他事务insert的数据(为什么?因为隔离性实现是对数据加锁完成的,而insert待插入的数据因为并不存在,那么一般加锁无法屏蔽这类问题),会造成虽然大部分内容是可重复读的,但是insert的数据在可重复读情况被读取出来,导致多次查找时,会多查找出来新的记录,就如同产生了幻觉。这种现象,叫做幻读 (phantom read)。

2.2.4 串行化【Serializable】

对所有操作全部加锁,进行串行化,不会有问题,但是只要串行化,效率很低,几乎完全不会被采用。

两个终端都使用事务,当A进行更新的时候,会一直阻塞,直到终端B提交后才可以。
recording.gif
实际这种完全不会被采用。

2.2.5 总结

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

image.png

3. 事务的一致性

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

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

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

相关文章

DOM遍历

DOM 遍历是指在 HTML 文档中导航和定位元素的过程。通过 DOM 遍历,您可以在文档中移动并查找特定的元素,以便对其进行操作或者检索信息。 寻找子元素 //DOM遍历 const h1 document.querySelector(h1);//寻找子元素 console.log(h1.querySelectorAll(.…

华为鸿蒙正式杀入工业自动化,反攻开始了!

导语 大家好,我是社长,老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 在近日举行的2024华为开发者大会上,华龙讯达与华为共同发布了基于鸿蒙内核技术的“HualongOS 华龙工业操作系统”,这一里…

运维.Linux下执行定时任务(上:Cron简介与用法解析)

运维专题 Linux下执行定时任务(上:Cron简介与用法解析) - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAd…

基于飞腾腾云S2500的ATS部署及调优指南(反向代理篇)

【写在前面】 飞腾开发者平台是基于飞腾自身强大的技术基础和开放能力,聚合行业内优秀资源而打造的。该平台覆盖了操作系统、算法、数据库、安全、平台工具、虚拟化、存储、网络、固件等多个前沿技术领域,包含了应用使能套件、软件仓库、软件支持、软件适…

TensorRt(6)yolov3.weight转换、onnx_graphsurgeon和c++ api实现添加NMS

前面博文 【opencv dnn模块 示例(3) 目标检测 object_detection (2) YOLO object detection】 介绍了 使用opencv dnn模块加载yolo weights格式模型的详细说明。 又在博文 【TensorRt(4)yolov3加载测试】 说明了如何将onnx编译为tensorrt格式并使用的方式…

[论文笔记]Mixture-of-Agents Enhances Large Language Model Capabilities

引言 今天带来一篇多智能体的论文笔记,Mixture-of-Agents Enhances Large Language Model Capabilities。 随着LLMs数量的增加,如何利用多个LLMs的集体专业知识是一个令人兴奋的开放方向。为了实现这个目标,作者提出了一种新的方法&#xf…

【Mac】iTerm for mac(终端工具)软件介绍及安装教程

软件介绍 iTerm 是 macOS 上一个非常受欢迎的终端仿真器,提供了比默认的 Terminal 应用更多的功能和定制选项。它是一款开源软件,主要用于命令行界面的操作和开发者工具。 主要特点和功能: 分页和标签: iTerm 允许用户在单个窗…

centOS 7安装gitlab

主要参考: CentOS-7 下 GitLab 安装部署教程_centos7 安装gitlab-CSDN博客 但是由于我本身服务器配置很小(2核2G),所以运行的时候报错: execute[clear the gitlab-rails cache] (gitlab::gitlab-rails line 561) had an error: Mixlib::Sh…

vue3使用v-html实现文本关键词变色

首先看应用场景 这有一段文本内容,是项目的简介,想要实现将文本中的关键词进行变色处理 有如下关键词 实现思路 遍历文本内容,找到关键词,并使用某种方法更改其字体样式。经过搜寻资料决定采用v-html实现,但是v-h…

哈夫曼编码

一.哈夫曼树 哈夫曼树(Huffman Tree)是一种用于数据压缩的二叉树。它基于字符出现的频率构建,使得高频字符使用较短的编码,低频字符使用较长的编码,从而实现数据压缩。哈夫曼树也被称为最优二叉树或哈夫曼编码树。 哈夫…

中医背诵笔记(黄帝内经、伤寒论等)

目录 黄帝内经上古天真论今人和古人之差异(精神内守,病安从来?)男女每个年龄阶段身体状态至人、圣人、贤人 宣明五气篇五脏所藏 与 五脏所主七情与情绪与气的关系 天干地支天干地支与脏腑经络的关系 黄帝内经 上古天真论 今人和…

【模型】5分钟了解决策树是一个什么模型

本站原创文章,转载请说明来自《老饼讲解-机器学习》[www.bbbdata.com(https://www.bbbdata.com/ml) 决策树模型是机器学习中不可不学的模型之一,本文简单直接地快速讲解决策树是什么,如何实现。 一、决策树模型 决策树一般包括ID3决策树&am…

Qt:2.环境搭建

目录 1.搭建需要的三个组件: 2.下载Qt安装包: 3.安装qt: 4.配置环境变量: 1.搭建需要的三个组件: C编译器(gcc,cl.exe等)Qt的SDK:软件开发工具包,Windows…

java复习宝典,jdbc与mysql数据库

一.java 1.面向对象知识 (1)类和对象 类:若干具有相同属性和行为的对象的群体或者抽象,类是创建对象的模板,由属性和行为两部分组成。 类是对象的概括或者抽象,对象是类的实例化。 举例:例如车有很多类型&#xf…

从传统到智能:视频汇聚EasyCVR+AI视频监控如何助力仓储的智能化转型

随着物流行业的快速发展和市场竞争的加剧,仓储管理对于保证货物安全、提高运营效率显得尤为重要。传统的仓储监控方式已难以满足现代仓储管理的需求,因此,仓储视频智能监控解决方案应运而生。方案通过集成先进的视频监控技术、智能分析算法、…

xhs 旋转验证码剖析和协议算法实现

【作者主页】:小鱼神1024 【擅长领域】:JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码&#…

Vue + SpringBoot 实现文件的断点上传、秒传,存储到Minio

一、前端 1. 计算文件的md5值 前端页面使用的elment-plus的el-upload组件。 <el-upload action"#" :multiple"true" :auto-upload"false" :on-change"handleChange" :show-file-list"false"><FileButton content&…

【系统架构设计师】六、信息系统基础知识(定义|分类|企业信息化系统|生命周期|建设原则|开发方法)

目录 一、信息系统的定义 二、信息系统的分类 三、企业使用的信息化系统 四、信息系统的生命周期 五、信息系统建设原则 六、信息系统的开发方法 6.1 结构化方法 6.2 原型法 6.3 构件化开发方法 6.4 面向服务的方法 6.5 面向对象的方法 6.6 敏捷方法 历年真题考情&#x…

Linux基础 - 存储结构与管理硬盘

目录 零. 简介 一. 文件系统 Ubuntu 文件系统结构&#xff1a; 路径: 二. 硬盘管理 零. 简介 Linux 文件系统是一种用于组织和存储文件、目录以及相关数据的架构。 常见的 Linux 文件系统有&#xff1a; Ext4&#xff08;Fourth Extended File System&#xff09;&#…

Java中Stream的特性

Stream新特性 被称之为Stream流&#xff0c;用于操作集合或者数组中的数据 优势&#xff1a;Stream流大量的结合了Lambda的语法风格&#xff0c;代码更简洁&#xff0c;可读性更好 使用步骤 先获取数据源&#xff0c;获取Stream流 Collect…