【MySQL】 -- 事务
如果对表中的数据进行CRUD操作时,不加控制,会带来一些问题。
比如下面这种场景:
有一个tickets表,这个数据库被两个客户端机器A和B用时连接对此表进行操作。客户端A检查tickets表中还有一张票的时候,将票出售了,而火车票的总数是一个固定值,客户端A此时还没有来得及更新数据库
这时客户端B检查了票数,发现还有一张,又卖了一次票。这种情况,就出现了同一张票被卖了两次的场景。
这就是在进行CRUD时,不加控制带来的问题。
只要当进进行CRUD时满足以下属性,才能解决上面的问题:
- 买票的过程得是原子的
- 买票互相应该不能影响
- 买完票应该要永久有效
- 买前,和买后都要是确定的状态
而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
可以查看。
1.2 事务的提交方式
事务的提交方式常见的有两种
- 自动提交
- 手动提交
使用show variables like 'autocommit';
可以查看事务提交的方式。
ON
表示为自动提交。
可以通过set autocommit
来更改自动提交模式。值为0,表示禁止自动提交。
值为1,表示开启自动提交。
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;
可以查看数据库的连接情况。
除此之外还需要将mysql的默认隔离级别设置成读未提交。
set global transaction isolation level READ UNCOMMITTED;
使用此命令设置完成后,重启客户端进行连接隔离级别才会生效。
先查看事务是否是自动提交,使用show variables like 'autocommit';
命令进行查看。
ON表示开启自动提交。以下提交的方式都是自动提交的。
1.3.1 开始一个事务
开始一个事务,可以使用being
或者start transaction
。
1.3.2 创建一个保存点
使用savepoint 保存点名
进行设置一个保存点
1.3.3 回滚到保存点
使用rollback to 保存点名
即可回滚到指定的保存点中。
使用rollback
可以直接回滚到最开始。
使用示例-事务的开始和回滚
此时另一个客户端在查询时,也可以查询到。做到了一致性。
这样两个客户端同时操作一个表的时候,就可以有效的解决冲突了。
事务使用示例-自动回滚
当提交方式为自动提交的时候,客户端崩溃的后,MySQL会自动回滚。(隔离级别设置为提交未读)
在客户端A中使用事务进行插入。如下。
插入一条记录后,从另一个客户端B中就可以查询到,如下:
此时,客户端A崩溃了,那么MySQL就会自动回滚。
自动回滚后,在客户端B中就无法查询到插入的这条记录了。
事务使用示例-提交后,客户端崩溃后,MySQL的数据不会在受到影响。(持久化特性)
在客户端A事务中插入一条记录,然后手动提交,客户端A崩溃。
此时在另一个客户端B中进行查询,依然可以查询到。
事务做到了数据持久化,不会被影响。
事务使用示例-begin操作会自动更改提交方式,不会受MySQL是否自动提交影响
事务使用示例-单条 SQL 与事务的关系
单条SQL:
此时客户端B在进行查询的时候就无法查询到此记录。
事务:
此时客户端B在进行查询的时候依然可以查询到此记录。数据已经被持久化了。
1.4 总结
- 只要输入
begin
或者start transaction
,事务便必须要通过commit
提交,才会持久化,与是 否设置set autocommit
无关。 - 事务可以手动回滚,同时,当操作异常,MySQL会自动回滚
- 对于
InnoDB
每一条SQL
语言都默认封装成事务,自动提交。(select
有特殊情况,因为 MySQL 有 MVCC )
事务操作注意事项:
- 如果没有设置保存点,也可以回滚,只能回滚到事务的开始。直接使用 rollback(前提是事务 还没有提交)。
- 如果一个事务被提交了(commit),则不可以回退(rollback)
- 可以选择回退到哪个保存点
InnoDB
支持事务,MyISAM
不支持事务- 开始事务可以使
start transaction
或者begin
。begin
更简洁 推荐使用。
2. 事务隔离级别
- MySQL服务可能会同时被多个客户端进程(线程)访问,访问的方式以事务的方式进行。
- 一个事务可能由多条SQL语句构成,也就意味着任何一个事务,都有执行前、执行中和执行后三个阶段,而所谓的原子性就是让用户层要么看到执行前,要么看到执行后,执行中如果出现问题,可以随时进行回滚,所以单个事务对用户表现出来的特性就是原子性。
- 但毕竟每个事务都有一个执行的过程,在多个事务各自执行自己的多条SQL时,仍然可能会出现互相影响的情况,比如多个事务同时访问同一张表,甚至是表中的同一条记录。
- 数据库中,为了保证事务执行过程中尽量不受干扰,就有了一个重要特征:隔离性
- 数据库中,允许事务受不同程度的干扰,就有了一种重要特征:隔离级别
数据库的隔离级别一共有以下四种。
- 读未提交【Read Uncommitted】: 在该隔离级别,所有的事务都可以看到其他事务没有提交的 执行结果。(实际生产中不可能使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多 并发问题,如脏读,幻读,不可重复读等,上面为了做实验方便,用的就是这个隔离性。
- 读提交【Read Committed】 :该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默 认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别会引起不可重复读,即一个事务执行时,如果多次 select, 可能得到不同的结果。
- 可重复读【Repeatable Read】: 这是 MySQL 默认的隔离级别,它确保同一个事务,在执行中,多次读取操作数据时,会看到同样的数据行。但是会有幻读问题。
- 串行化【Serializable】: 这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突, 从而解决了幻读的问题。它在每个读的数据行上面加上共享锁,。但是可能会导致超时和锁竞争 (这种隔离级别太极端,实际生产基本不使用)
2.1 查看隔离性
SELECT @@global.tx_isolation;
:查看全局的隔离级别
SELECT @@session.tx_isolation;
或者SELECT @@tx_isolation;
:查看当前会话的隔离级别
2.2 设置隔离级别
- 设置当前会话 or 全局隔离级别语法:
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | Serializable}
比如设置当前会话隔离级别为Serializable。
设置全局隔离性的话,另起一个会话就会被影响。重启MySQL客户端生效
2.2.1 读未提交【Read Uncommitted】
该隔离级别,效率虽然很高,但是问题太多,严重不建议使用。
问题如下:
1、将事务的隔离级别设置为Read Uncommitted
2、在一个终端A中开启事务,然后插入一条记录。不进行提交。
3、在另一个终端中进行查询
这就是Read Uncommitted隔离级别做严重的问题,读到了未提交的数据。这种现象称之为脏读~
2.2.2 读提交【Read Committed】
按照命名来看,对比读未提交,读提交只读已提交的数据。但是这种隔离级别有新的问题。读到的值不同。问题如下:
1、将隔离级别设置为Read Committed
2、开启事务,不提交在另一个客户端进行查询
在另一个终端中读不到。
3、进行提交,在另一个终端再次读取。
终端A使用commit
提交后,在终端B中就可以查到了。
到此,读提交解决了读未提交的问题。
但是,如果在终端A更新插入一条记录,不提交,终端B就能读到了。回到了读未提交的现象。
终端B还是读到了
这种现象叫做不可重复读,解决这个问题,又有了新的隔离级别。 可重复读【Repeatable Read】
2.2.3 可重复读【Repeatable Read】
这种隔离级别解决了读未提交和读提交的问题,但是又带来了幻读的问题。如下:
1、设置隔离级别为Repeatable Read
2、开启事务,插入记录
不提交,此时在另一个终端就无法进行查询到。解决读未提交的问题。
继续在终端A中插入一条记录
此时在终端中就能查询到了。
继续插入,不提交,另一个终端也无法查到。
同样的,在终端A中插入一条记录,并提交结束事务。
然后再终端B查询终端Acommit后的纪律。
但是,多次查询后,在终端B中无法查询到A commit到的记录。
这倒也没有什么影响,也符合可重复的特点。
但是,一般的数据库在可重复读情况的时候,无法屏蔽其他事务insert的数据(为什么?因为隔离性实现是对数据加锁完成的,而insert待插入的数据因为并不存在,那么一般加锁无法屏蔽这类问题),会造成虽然大部分内容是可重复读的,但是insert的数据在可重复读情况被读取出来,导致多次查找时,会多查找出来新的记录,就如同产生了幻觉。这种现象,叫做幻读 (phantom read)。
2.2.4 串行化【Serializable】
对所有操作全部加锁,进行串行化,不会有问题,但是只要串行化,效率很低,几乎完全不会被采用。
两个终端都使用事务,当A进行更新的时候,会一直阻塞,直到终端B提交后才可以。
实际这种完全不会被采用。
2.2.5 总结
- 事务隔离级别越严格,安全性越高,但数据库的并发性能也就越低,往往需要在两者之间找一个平衡点。
- 不可重复读的重点是修改和删除:同样的条件, 你读取过的数据,再次读取出来发现值不一样了
- 幻读的重点在于新增:同样的条件, 第1次和第2次读出来的记录数不一样
- 说明: mysql 默认的隔离级别是可重复读,一般情况下不要修改
- 上面的例子可以看出,事务也有长短事务这样的概念。事务间互相影响,指的是事务在并行执行的 时候,即都没有commit的时候,影响会比较大。
3. 事务的一致性
- 事务执行的结果,必须使数据库从一个一致性状态,变到另一个一致性状态。当数据库只包含事务 成功提交的结果时,数据库处于一致性状态。如果系统运行发生中断,某个事务尚未完成而被迫中 断,而改未完成的事务对数据库所做的修改已被写入数据库,此时数据库就处于一种不正确(不一 致)的状态。因此一致性是通过原子性来保证的。
- 其实一致性和用户的业务逻辑强相关,一般MySQL提供技术支持,但是一致性还是要用户业务逻辑 做支撑,也就是说,一致性,是由用户决定的。
- 而技术上,通过AID保证C
相关文章:

【MySQL】 -- 事务
如果对表中的数据进行CRUD操作时,不加控制,会带来一些问题。 比如下面这种场景: 有一个tickets表,这个数据库被两个客户端机器A和B用时连接对此表进行操作。客户端A检查tickets表中还有一张票的时候,将票出售了&#x…...
c#调用c++生成的dll,c++端使用opencv, c#端使用OpenCvSharp, 返回一张图像
c代码: // OpenCVImageLibrary.cpp #include <opencv2/opencv.hpp> #include <vector> extern "C" { __declspec(dllexport) unsigned char* ReadImageToBGR(const char* filePath, int* width, int* height, int* step) { cv::Mat i…...
【Android面试八股文】你能说一说View绘制流程与自定义View注意点吗?
文章目录 一、自定义View的构造函数以及各参数的用法二、自定义View的几种方式三、自定义View的绘制流程四、自定义View需要注意的一些点五、举个例子一、自定义View的构造函数以及各参数的用法 在Android中,自定义View通常需要提供多个构造函数,以适应不同的使用场景。主要…...

【第24章】Vue实战篇之用户信息展示
文章目录 前言一、准备1. 获取用户信息2. 存储用户信息3. 加载用户信息 二、用户信息1.昵称2.头像 三、展示总结 前言 这里我们来展示用户昵称和头像。 一、准备 1. 获取用户信息 export const userInfoService ()>{return request.get(/user/info) }2. 存储用户信息 i…...

“打造智能售货机系统,基于ruoyi微服务版本生成基础代码“
目录 # 开篇 1. 菜单 2. 字典配置 3. 表配置 3.1 导入表 3.2 区域管理 3.3 合作商管理 3.4 点位管理 4. 代码导入 4.1 后端代码生成 4.2 前端代码生成 5. 数据库代码执行 6. 点位管理菜单顺序修改 7. 页面展示 8. 附加设备表 8.1 新增设备管理菜单 8.2 创建字…...

oracle12c到19c adg搭建(五)dg搭建后进行切换19c进行数据字典升级
一、备库切主库升级 12c切换为19c主库的时候是由低版本到高版本所以cdb和pdb的数据字典需要进行升级才可以让数据与软件版本兼容。 1.1切换 SQL> alter database recover managed standby database finish; Database altered. SQL> alter database commit to switcho…...
在公司的一些笔记
6.19 记住挂载在windows上的账户是DAHUATECH\401593,不是401593Windows与linux不能同时挂载在虚拟盘上 6.21 /******************************************************************************* pdc_ledSy7806e.c* * Description: 提供I2C访问sy7806e。 * * …...
2020C++等级考试二级真题题解
202012数组指定部分逆序重放c #include <iostream> using namespace std; int main() {int a[110];int n, k;cin >> n >> k;for (int i 0; i < n; i) {cin >> a[i];}for (int i 0; i < k / 2; i) {swap(a[i], a[k - 1 - i]);}for (int i 0…...
面试官:聊聊 nextTick
前言 在最近的面试中,不少面试官叫我聊聊 nextTick,nextTick 是个啥,这篇文章咱来好好聊聊! 我的回答 nextTick 是官方提供的一个异步方法,用于在 DOM 更新之后执行回调。正好在我的项目中用到了,就拿它来形容一下,大概的场景是渲染一个列表,每次点击按钮就会往列表后…...
shell编程之条件语句(shell脚本)
条件测试操作 要使shell脚本程序具备一定的“智能”,面临的第一个问题就是如何区分不同的情况以确定执行何种操作。例如,当磁盘使用率超过95%时,发送告警信息;当备份目录不存在时,能够自动创建;当源码编译程序时,若配置失败则不再继续安装等。 shell环境根据命令执行后…...
QT中QSettings的使用系列之二:保存和恢复应用程序主窗口
1、核心代码 #include "widget.h" #include "ui_widget.h" #include <QSettings> #include <QDebug> #include <QColo...
Linux系统上安装Miniconda并安装特定版本的Python
要在Linux系统上安装Miniconda并安装特定版本的Python(例如3.10.12),请按照以下步骤进行操作: 1. 下载并安装Miniconda 下载Miniconda安装脚本: 使用wget或curl下载Miniconda安装脚本。以下是使用wget的命令ÿ…...
解决Qt中 -lGL无法找到的问题
在使用Qt Creator创建并编译新项目时,可能会遇到以下错误: /usr/bin/ld: cannot find -lGL collect2: error: ld returned 1 exit status make: *** [untitled1] Error 1 18:07:41: The process "/usr/bin/make" exited with code 2. Error w…...
【重要】《HTML趣味编程》专栏内资源的下载链接
目录 关于专栏 博主简介 专栏内资源的下载链接 写在后面 关于专栏 本专栏将持续更新,至少含有30个案例,后续随着案例的增加可能会涨价,欢迎大家尽早订阅!(订阅后可查看专栏内所有文章,并且可以下载专栏内的所有资源) 博主简介 ⭐ 2024年百度文心智能体大赛 Top1⭐…...

苍穹外卖环境搭建
一、前端环境搭建 ①整体结构 ②前端工程基于nginx运行 启动nginx:双击 nginx.exe 即可启动 nginx 服务,访问端口号为 80 进入浏览器地址输入locallhost回车 二、后端环境搭建 后端初始工程基于maven进行项目构建,并且进行分模块开发 (1) idea打开初始…...

切割游戏介绍
简介 上大学时,在学校实验室里玩过一个貌似使用VC写的小游戏,一个小球在界面上四处游荡,玩家使用鼠标切割背景,将背景切割剩余到一定的百分比后,就胜利了,后边的背景图会全部展示出来。 使用qt的qml技术&a…...
对接Paypal、Stripe支付简单流程
一、Stripe卡支付简单流程: #mermaid-svg-bZxQh1bt4Z8agjJg {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-bZxQh1bt4Z8agjJg .error-icon{fill:#552222;}#mermaid-svg-bZxQh1bt4Z8agjJg .error-text{fi…...

微服务中不同服务使用openfeign 相互调用
首先 我们上文 已经知道了 nacos 的注册服务,现在 我们 在不同服务中相互调用就可以使用openfeign 直接调用,而不是 再写冗余的调用代码啦 首先 我们的微服务组件如下 因为我这个微服务是我在 员工登录demo 中 拆出来的,在userlogin模块中…...

社区项目-项目介绍环境搭建
文章目录 1.技术选型2.原型设计1.安装AxureRP2.进行汉化3.载入元件库4.基本设计 3.元数建模1.安装元数建模软件2.新建项目3.新增一个刷题模块主题域4.新增数据表 subject_category5.新增关系图,将表拖过来6.新增题目标签表7.新增题目信息表8.新增单选表、多选表、判…...

【论文阅读】-- Omnisketch:高效的多维任意谓词高速流分析
Omnisketch:高效的多维任意谓词高速流分析 摘要1 引言2 预备知识及相关工作3 OMNISKETCH:使用任意谓词估计频率3.1 Sketch S0:Count-Min with rid-sets 用于估计带有谓词的查询3.2 Sketch S1 (OmniSketch):…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...