40.MySQL事务

1.事务的作用

事务用于保证数据的一致性,它由一组相关的 dml (update delete insert) 语句组成,该组的 dml (update delete insert) 语句要么全部成功,要么全部失败

如:转账就要用事务来处理,用以保证数据的一致性。

假设张三给李四转100块:

银行后台有一张简单的数据库余额表:

为了完成转账这件事,银行后台需要执行这两条sql语句:

这时候就会出现三种情况:

1.第一条语句执行失败,第二条语句执行成功,结果出错;

2.第一条语句执行成功,第二条语句执行失败,结果出错;

3.两条语句全部执行失败;

4.两条语句全部执行成功;

假如你是银行的话,当然会希望这两条语句要么同时失败,要么同时成功。

这就引出我们的需求:两个sql语句作为一个整体,用以保证数据的一致性。

当执行事务操作时 (dml (update delete insert) 语句) ,mysql 会在表上加锁,防止其它用户改表的数据。这对用户来讲是非常重要的。

2.事务的操作

2.1开始一个事务

基本语法:

start transaction; -- 开始一个事务

2.2设置保存点

保存点 (savepoint), 保存点是事务中的点,用于取消部分事务,当结束事务时(commit),会自动的删除该事务所定义的所有保存点。

当执行回退事务时,通过指定保存点可以回退到指定的点。

基本语法:

savepoint 保存点名; -- 设置保存点

2.3回退事务

基本语法:

rollback to 保存点名; -- 回退事务

2.4回退全部事务

基本语法:

rollback; -- 回退全部事务

2.5提交事务

使用 commit 语句可以提交事务。当执行了 commit 语句子后,会确认事务的变化、结束事务、删除保存点、释放锁,数据生效。

当使用 commit 语句结束事务子后,其它会话【其他用户的连接】将可以查看到事务变化后的新数据。

类似于下图。而让用户2在用户1开始事务时对用户1的操作的数据不可见的功能就叫做隔离

基本语法:

commit; -- 提交事务,所有的操作生效,不能回退

2.6示例

先创建一个简单的表:

CREATE TABLE t03 (id INT,`name` VARCHAR(32)
);

开启一个事务:

START TRANSACTION;

插入一条数据:

insert into t03 values(1,'tom');

设置一个保存点:

savepoint a;

再次插入一条数据:

insert into t03 values(2,'Jack');

再设置一个保存点:

savepoint b;

再次插入一条数据:

insert into t03 values(3,'lucy');

回滚到保存点a:

ROLLBACK TO a;

回滚全部:回到了最开始刚开启事务时的样子。

ROLLBACK;

再次插入一条数据:

insert into t01 values(4,'jep');

提交事务:

COMMIT;

再次回滚全部:

ROLLBACK;

数据已经生效,保存点全部被删除,回滚不了了。

3.事务的使用细节

3.1 没有设置保存点

如果不开始事务,默认情况下,dml 操作是自动提交的,不能回滚。

如果开始一个事务,你没有创建保存点。你可以执行 rollback,默认就是回退到你事务开始的状态.

3.2 多个保存点

你也可以在这个事务中 (还没有提交时), 创建多个保存点。

比如:

savepoint aaa;

执行 dml;

savepoint bbb;

你可以在事务没有提交前,选择回退到哪个保存点。

3.3 存储引擎

mysql 的事务机制需要 innodb 的存储引擎才可以使用,myisam 不好使。

3.4 开始事务方式

开始一个事务有两种方式:

start transaction;
set autocommit=off;

4.四种隔离级别

4.1隔离的基本介绍

事务隔离级别介绍:

  1. 多个连接开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个连接在获取数据时的准确性。(通俗解释)
  2. 如果不考虑隔离性,可能会引发如下问题:
    ➢ 脏读
    ➢ 不可重复读
    ➢ 幻读

举个例子:当MySQL同时又两个连接C1,C2

C1在对这个表进行dml操作的时候,C2再查询这张表的时候所看到的是怎样的一种数据,取决于C2的隔离级别。

4.2不做隔离引发的问题

①脏读(dirty read):

当一个事务读取另一个事务尚未提交修改时,产生脏读。


②不可重复读(nonrepeatable read):

同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生不可重复读。


③幻读(phantom read):

同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻读。

4.3事务隔离级别

概念:Mysql隔离级别定义了事务与事务之间的隔离程度

Mysql隔离级别(4种)

脏读

不可重复读

幻读

加锁读

加锁写

读未提交(Read uncommitted)

V

V

V

不加锁

加锁(排他锁)

读已提交(Read committed)

x

V

V

不加锁

加锁(排他锁)

可重复读(Repeatable read)

x

x

x

不加锁

加锁(排他锁 + 间隙锁 / 临键锁)

可串行化(Serializable)

x

x

x

加锁

加锁(排他锁)

说明:V 可能出现 ×不会出现

4.4事务隔离级别的特性

mysql事务ACID

  • 事务的acid特性
    1. 原子性(Atomicity)
      原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
    2. 一致性(Consistency)
      事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
    3. 隔离性(Isolation)
      事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
    4. 持久性(Durability)
      持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

4.5事务隔离级别的设置与查看

mysql事务隔离级别

  1. 查看当前会话隔离级别(用户临时登录时的隔离级别)
select @@tx_isolation;  
  1. 查看系统当前隔离级别(所有用户登录时默认的隔离级别)
select @@global.tx_isolation;  
  1. 设置当前会话隔离级别
set session transaction isolation level [Read uncommitted/Read committed/repeatable read/Serializable]; 
  1. 设置系统当前隔离级别
set global transaction isolation level [Read uncommitted/Read committed/repeatable read/Serializable];  
  1. mysql 默认的事务隔离级别是 repeatable read ,一般情况下,没有特殊要求,没有必要修改(因为该级别可以满足绝大部分项目需求)

真的想改mysql系统默认隔离级别的话:

全局修改,修改 mysql.ini 配置文件,在最后加上transaction-isolation = REPEATABLE-READ
--可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.

之后重启mysql服务,就完成了修改。

4.6事务隔离级别的演示

①读未提交

左右都开一个mysql的连接,左边我们取做连接1,右边取做连接2;

选取一个数据库:

use mysql_learn;

在该数据库下创建一个表:

create table account (id int,name varchar(32),money int);

查看一下两边的事务隔离级别:

select @@tx_isolation;

连接1的为REPEATABLE-READ(可重复读),也就是mysql默认的事务隔离级别;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+

连接2的设置为读未提交:

set session transaction isolation level Read uncommitted;

再次查看一下连接2的隔离级别为READ-UNCOMMITTED(读未提交):

select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+

现在我们在两个连接上同时开启事务:

连接2的事务中查看一下该表:

我们在连接1执行几条dml语句:

insert into account values(100,'tom',3000);
insert into account values(200,'jack',5000);
update account set money = money + 100 where id = 100;

注意!我们连接1和连接2的事务都是没有提交的,但是此刻在连接2查看一下这张表:

连接1提交一下事务,再在连接2查看一下这张表:

在并行的连接1和连接2中的事务中,我们会发现,在连接2中还未提交的事务中多次查看account表的结果会由于连接1中的事务中的dml操作以及事务的提交而变化。

这也就是“读未提交”这个隔离级别可能会造成赃读,不可重复读,幻读等问题。

②读已提交

将连接2的事务也提交一下(其实什么都没做,只是演示);

现在将连接2的隔离级别设置为:Read committed(读已提交);

 set session transaction isolation level Read committed;

现在,将连接1和连接2中同时开启事务:

连接2的事务中查看一下该表:

在连接1的事务中执行几句dml:

insert into account values(300,'lucy',9999);
insert into account values(400,'chen',10000);
update account set money = money + 10000 where id = 300;

注意!此刻连接1和2的事务都是没有提交的,我们在连接2的事务中查看一下该表:

可以发现,连接1未提交的事务中做的修改,没有在连接2的事务中查看到;

将连接1的事务提交一下,再在没有提交的连接2开启的事务中查看该表:

在并行的连接1和连接2中的事务中,可以发现在没有提交的连接2开启的事务当中,对account表的查看结果受到了连接1中的含有dml操作的事务的提交而改变。

在“读已提交”的隔离级别下,可能会引起不可重复读以及幻读问题。

③可重复读

将连接2的事务提交一下,并且将其隔离级别设置为Repeatable read(可重复读):

commit;
set session transaction isolation level repeatable read; 

连接1和连接2再次开启事务:

连接2的事务中查看一下该表:

在连接1的事务中执行几句dml:

insert into account values(500,'kimi',8888);
insert into account values(600,'liu',20000);
update account set money = money - 1000 where id = 500;

注意!此刻连接1和2的事务都是没有提交的,我们在连接2的事务中查看一下该表:

可以发现,连接1未提交的事务中做的修改,没有在连接2的事务中查看到;

将连接1的事务提交一下,再在没有提交的连接2开启的事务中查看该表:

在并行的连接1和连接2中的事务中,可以发现在没有提交的连接2开启的事务当中对account表的多次查看结果并没有受到已经提交了的连接1开启的事务的dml操作以及提交而改变。

也就是说可重复读这个隔离级别不会有赃读,不可重复读以及幻读等问题。

④可串行化

将连接2的事务提交一下,并且将其隔离级别设置为:Serializable(可串行化);

commit;
set session transaction isolation level Serializable; 

连接1和连接2再次开启事务:

连接2的事务中查看一下该表:

在连接1的事务中执行几句dml:

insert into account values(700,'chuyi',22222);
insert into account values(800,'shiwu',33333);
update account set money = money + 11111 where id = 700;

注意!此刻连接1和2的事务都是没有提交的,我们在连接2的事务中查看一下该表:

会发现回车键输入无效,连接2的事务中查看不了正在被连接1事务操作的account这张表!

这就说明account这张表对于隔离级别为“可串行化”的连接2开启的事务来说是被上了锁的。

我们将连接1的事务提交一下:

再在没有提交的连接2开启的事务中查看该表:

在实际上并行的连接1和连接2中的事务中,由于可串行化的隔离级别的加锁机制,使得连接1和连接2中的事务得到了形式上串行的效果,并且也达到了数据同步得效果。

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

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

相关文章

java导入pdf(携带动态表格,图片,纯java不需要模板)

java导出pdf文件一、介绍二、准备三、实现效果四、代码一、介绍 上一篇文章(java使用freemarker操作word(携带动态表格,图片))https://blog.csdn.net/weixin_45853881/article/details/129298494 紧跟上文&#xff0c…

【dropdown组件填坑指南】鼠标从触发元素到下拉框中间间隙时,下拉框消失,怎么解决?

开发dropdown组件填坑之hideDelay 引言 在开发下拉菜单(dropdown)或弹出框(popover)组件时,一个常见的用户体验问题就是鼠标移出触发区域后,弹出内容立即消失,这会导致用户无法移动到弹出内容上…

Linux I/O 函数完整清单

Linux I/O 函数完整清单 1. 基础 I/O 函数 1.1 基本读写 #include <unistd.h>ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count);1.2 位置指定读写 #include <unistd.h>ssize_t pread(int fd, void *buf, siz…

面经——电子电路技术知识详解

电子电路技术知识详解 目录 德摩根定律周期性矩形波产生方法自激振荡器原理与设计晶体管温度效应分析反向饱和电流影响因素放大电路负反馈类型判断正弦波90相移电路直接耦合放大器的缺点二阶有源低通滤波器分析开关电源与线性电源对比 德摩根定律 德摩根定律&#xff08;De …

docker 安装 gitlab

null文章浏览阅读445次。问题&#xff1a;运行 docker run hello-world 报错。原因&#xff1a;原镜像源网络不稳定。https://blog.csdn.net/sszdzq/article/details/145733419 镜像获取 在线下载 docker pull gitlab/gitlab-ce:17.11.1-ce.0 离线获取 创建运行 sudo docke…

PHP中的日期/时间处理之Carbon组件

日常开发中&#xff0c;我们会经常用到日期和时间的操作&#xff0c;但官方的一般操作比较复杂&#xff0c;需要大量的时间进行格式化问题和大量计算等等。Carbon组件 可以帮助我们在 PHP 开发中处理日期/时间变得更加简单、更语义化&#xff0c;从而使得我们的代码更容易阅读和…

学习嵌入式第十八天

文章目录1.数据结构1.概念2.衡量代码质量和效率1.时间复杂度2.空间复杂度3.数据结构分类1.逻辑结构2.存储结构3.常见的数据结构2.链表1.与顺序表的区别2.链表分类1.单向链表1.定义链表节点类型2.空链表的创建3.链表的头插法4.链表的遍历5.链表元素删除3.makefile习题1.数据结构…

基于SpringBoot+Vue实现校园商铺系统

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验&#xff0c;被多个学校常年聘为校外企业导师&#xff0c;指导学生毕业设计并参…

从资源闲置到弹性高吞吐,JuiceFS 如何构建 70GB/s 吞吐的缓存池?

AI 模型的训练与推理对存储系统提出了极为严苛的要求&#xff0c;特别是在高吞吐、高并发以及对海量小文件的高效处理方面&#xff0c;已成为三大主要挑战。尽管基于 Lustre 或 GPFS 的并行文件系统具备出色的性能&#xff0c;但其成本高昂、吞吐能力与容量强耦合&#xff0c;可…

提升JVM性能之CMS垃圾回收器的优化分析与案例剖析

这里写目录标题一、CMS基本介绍二、CMS核心优化策略1. 避免并发模式失败&#xff08;Concurrent Mode Failure&#xff09;2. 减少内存碎片3. 调优并发阶段耗时4. 新生代优化配合三、典型案例解析案例1&#xff1a;电商服务频繁Full GC案例2&#xff1a;金融交易系统碎片导致长…

Token系列 - 再谈稳定币

相关政策 2024年12月&#xff0c;欧洲《加密资产市场监管法案》正式成为法律2025年3月&#xff0c;日本细化了加密资产及稳定币的监管调整2025年5月&#xff0c;英国发布了关于稳定币发行、加密资产托管及加密资产公司财务稳健性的监管提案&#xff1b;2025年5月20日&#xff…

【20min 急速入门】使用Demucs进行音轨分离

创建环境 conda create --name mujica python3.10下载加速依赖 先用nvidia-smi检查机器使用的独显版本, 然后从pytorch官网下载对应的GPU版torch, torchaudio 比如我的是12.2, 就下载11.8版本的 pip3 install torch torchvision torchaudio --index-url https://download.p…

字节Seed发布扩散语言模型,推理速度达2146 tokens/s,比同规模自回归快5.4倍

用扩散模型写代码&#xff0c;不仅像开了倍速&#xff0c;改起来还特别灵活&#xff01;字节Seed最新发布扩散语言模型Seed Diffusion Preview&#xff0c;这款模型主要聚焦于代码生成领域&#xff0c;它的特别之处在于采用了离散状态扩散技术&#xff0c;在推理速度上表现出色…

海洋大地测量基准与水下导航系列之九我国海洋PNT最新技术进展(下)

三、海洋PNT技术装备研发与工程化应用 1.海底基准装备 研制了首批适应海洋环境的多型海底基准站装备&#xff0c;在我国南海海域成功布设了定位精度优于0.25m的海底大地测量试验基准网&#xff0c;实现了我国海底大地测量基准技术零的突破。基准方舱具备稳固、抗压、防腐、防…

入门MicroPython+ESP32:安装逗脑IDE及驱动

本篇文章将手把手带大家入门MicroPython ESP32&#xff0c;重点介绍逗脑IDE的安装过程以及相关驱动的安装。 一、下载逗脑IDE 要开始使用逗脑IDE&#xff0c;首先需要从官网下载最新版本。请访问以下网址进行下载&#xff1a;https://www.itprojects.cn/ide 下载时的界面大…

CentOS上部署Redis及其哨兵(Sentinel)模式

架构&#xff1a;说明我这里是伪集群的&#xff0c;redis 在同一台机器&#xff0c;Sentinel 只有一个&#xff0c;也存在单点故障问题只能当作开发环境使用&#xff0c;要满足生产至少是下面这种架构 ------------------- ------------------- ------------------- …

《软件测试与质量控制》实验报告二 单元测试

目 录 一、实验学时 二、实验目的 三、实验环境 &#xff08;一&#xff09;硬件环境&#xff1a; &#xff08;二&#xff09;软件环境&#xff1a; 四、实验内容 1、实验方案&#xff1a; 2、实验步骤&#xff1a; 3、设计思路&#xff1a; 1、安装JUnit和Eclemma…

k8s模式部署PolarDB-X

当前文档适配PolarDB-X V2.4.0 版本 环境描述&#xff1a; 部署机&#xff08;ops&#xff09;1x2.2x.2x8.116&#xff0c;部署机需要可以访问互联网。使用ansible进行部署&#xff0c;自行安装ansible。需要部署两个k8s集群&#xff0c;分别在其上安装一个polardb-x集群。 部…

Flask + YARA-Python*实现文件扫描功能

以下是一个 完整的 Web API 示例&#xff0c;使用 Flask YARA-Python 实现文件扫描功能&#xff0c;支持上传文件并返回 YARA 规则匹配结果。 ✅ 功能说明 提供一个 /scan 接口&#xff0c;支持文件上传使用预加载的 YARA 规则进行扫描返回 JSON 格式的匹配结果支持多规则、可…

WinForm之NumericUpDown控件

NumericUpDown&#xff08;数字上下控件&#xff09;是 WinForm 中专门用于输入和调整数值的控件&#xff0c;它结合了文本框和上下按钮&#xff0c;用户可通过点击按钮或直接输入来设置数值&#xff0c;且能严格限制数值范围&#xff08;最小值、最大值&#xff09;和步长&…