目录

一、什么是事务

(一)概念

(二)事务的四大属性

(三)事务的作用

(四)事务的提交方式

二、事务的启动、回滚与提交

(一)事务的启动、回滚与提交

(二)特殊情况

1、未 commit 事务,客户端崩溃,MySQL将自动回滚

2、commit 后,客户端崩溃,插入数据不受影响

3、手动开启事务不受自动提交事务影响

4、自动提交事务对单条 SQL 语句的影响

5、结论

三、事务的隔离级别

(二)事务的隔离级别

(三)四种隔离级别详解

1、读未提交

2、读已提交

3、可重复读

4、串行化


一、什么是事务

(一)概念

        MySQL 事务是指数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成,这些操作要么全部执行成功,要么全部不执行,是一个不可分割的工作单位。事务主要用于保证数据的一致性和完整性,特别是在需要多个操作同时成功或同时失败的场景中,比如银行转账、订单处理等。

(二)事务的四大属性

        事务的特性:

  • 原子性:事务中的所有操作要么全部完成,要么全部不完成,不会结束在中间某个状态;
  • 一致性:事务必须使数据库从一个一致性状态变换到另一个一致性状态;
  • 隔离性:多个事务并发执行时,一个事务的执行不会影响其他事务;
  • 持久性:一旦事务提交,其结果就是永久性的,即使系统崩溃也不会丢失。

(三)事务的作用

        事务的出现是为了简化程序开发时可能需要考虑的多种细节问题。例如:当银行账户 A 向银行账户 B 发起转账,首先需要现在 A 中扣除目标金额后再向B中添加目标金额,假如在扣除A账户的金额后出现了网络异常导致转账失败,这时的正常情况应该是账户A上返回了目标金额,事务的出现就使得该操作可以由 MySQL 自动完成而不需要程序员特殊处理。

(四)事务的提交方式

        事务的提交方式分为自动提交和手动提交。在先前学习MySQL语句时并没有对事务进行过特殊操作,这是因为 MySQL 默认设置自动提交。也就是每当执行一条语句后 MySQL自动将该语句进行事务的提交。

        查看事务自动提交方式:

//MySQl 默认打开自动提交
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.02 sec)
//设置自动提交事务关闭
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

二、事务的启动、回滚与提交

        为方便演示,需关闭事务自动提交、将事务的隔离级别设为最低并准备一个测试表:

//打开事务自动提交
mysql> set autocommit=1;
Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)
//设置隔离级别(需重启终端)
mysql> set global transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)
//创建测试表
mysql> create table test(-> id int primary key,-> name varchar(20) not null,-> salary decimal(10,2) default 0.0-> );
Query OK, 0 rows affected (0.02 sec)

(一)事务的启动、回滚与提交

//手动开启事务 (手动开始事务后该事务不受自动提交影响)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
//保存点1
mysql> savepoint save1;
Query OK, 0 rows affected (0.00 sec)mysql> insert into test values(1,'张三',5000);
Query OK, 1 row affected (0.00 sec)
//保存点2
mysql> savepoint save2;
Query OK, 0 rows affected (0.00 sec)mysql> insert into test values(2,'李四',4500);
Query OK, 1 row affected (0.00 sec)
//此时有两条记录
mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)
//回滚至保存点2
mysql> rollback to save2;
Query OK, 0 rows affected (0.00 sec)
//此时变为一条记录
mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
+----+--------+---------+
1 row in set (0.00 sec)
//回滚至最开始
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
//无记录
mysql> select * from test;
Empty set (0.00 sec)

        由上述结果可以看出,手动开启事务后将不受自动提交的影响。以上便是手动开启事务以及回滚操作。

(二)特殊情况

        以下情况都是最低隔离级别下的操作(读未提交),为方便说明开启两个终端进行演示:

1、未 commit 事务,客户端崩溃,MySQL将自动回滚

//客户端A
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> insert into test values(1, '张三', 5000);
Query OK, 1 row affected (0.00 sec)mysql> insert into test values(2, '李四', 4500);
Query OK, 1 row affected (0.00 sec)mysql> Aborted
[X@centos-414 ~]$ //客户端B
mysql> select * from test;
Empty set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
+----+--------+---------+
1 row in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)mysql> select * from test;
Empty set (0.01 sec)

2、commit 后,客户端崩溃,插入数据不受影响

//客户端A
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> insert into test values(1, '张三', 5000);
Query OK, 1 row affected (0.00 sec)mysql> insert into test values(2, '李四', 4500);
Query OK, 1 row affected (0.00 sec)mysql> commit;
Query OK, 0 rows affected (0.00 sec)mysql> Aborted//客户端B
mysql> select * from test;
Empty set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
+----+--------+---------+
1 row in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)

3、手动开启事务不受自动提交事务影响

//客户端A
mysql> set autocommit=1;
Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> insert into test values(3, '王五', 5500);
Query OK, 1 row affected (0.00 sec)mysql> Aborted//客户端B
mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
|  2 | 李四   | 4500.00 |
|  3 | 王五   | 5500.00 |
+----+--------+---------+
3 rows in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.01 sec)

4、自动提交事务对单条 SQL 语句的影响

//客户端A
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | OFF   |
+---------------+-------+
1 row in set (0.00 sec)mysql> insert into test values(3, '王五', 5500);
Query OK, 1 row affected (0.00 sec)mysql> Aborted//客户端B
mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
|  2 | 李四   | 4500.00 |
|  3 | 王五   | 5500.00 |
+----+--------+---------+
3 rows in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 张三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)

5、结论

  • 只要输入 begin 或者 start transaction,事务就必须通过 commit 提交才会持久化,与是否设置自动提交无关;
  • 对于 InnoDB 每一条 SQL 语言都默认封装成事务,自动提交。(select有特殊情况,因为 MySQL 有 MVCC );
  • 如果没有设置保存点,也可以回滚,只能回滚到事务的开始。直接使用 rollback(前提是事务还没有提交)
  • 如果一个事务被提交了则无法回退;
  • InnoDB 支持事务, MyISAM 不支持事务

三、事务的隔离级别

(一)什么是隔离性

        事务的隔离性是数据库事务的四大特性之一,它确保并发执行的多个事务相互独立,一个事务的操作不会被其他事务干扰,从而避免数据不一致问题。隔离性通过不同的隔离级别来控制事务之间的可见性和影响程度。

        查看隔离级别:

//查看全局隔离级别(一般默认为REPEATABLE-READ)
mysql> select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| READ-UNCOMMITTED      |
+-----------------------+
1 row in set, 1 warning (0.01 sec)
//查看此次会话隔离级别(一般开启MySQL客户端后该值由全局隔离级别进行初始化)
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客户端时的隔离级别由会话隔离级别等级决定。

        设置隔离级别:

//设置会话隔离级别
mysql> set session transaction isolation level serializable;
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 @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE   |
+----------------+
1 row in set, 1 warning (0.00 sec)

(二)事务的隔离级别

        SQL标准定义了四种隔离级别:

  1. 读未提交
    允许事务读取其他事务未提交的数据,可能出现脏读、不可重复读和幻读的情况;
  2. 读已提交
    只允许读取已提交的数据,避免脏读,但存在不可重复读和幻读的情况;
  3. 可重复读
    确保同一事务多次读取同一数据结果的一致性,可能会出现幻读的情况;
  4. 串行化
    最高隔离的级别,事务完全串行化,可避免所有并发问题,但性能低。

(三)四种隔离级别详解

1、读未提交

        在多个并行的会话中启动事务,一个事务在改动数据库哪怕没有commit提交,其他事务也是能够实时的看到它修改的数据。一个事务在执行中,读到另一个执行中事务的更新(或其他操作)但是未commit的数据,这种不合理的现象叫做脏读(dirty read)。

        上图可以看出,即使左端事务没有进行提交操作,但右端事务仍可以看到表的操作,这就是脏读。

2、读已提交

        事务A在commit提交事务之前,所做的修改是不会被其他事务看到的,一旦事务A发起commit之后,其他事务就能看到事务A对数据的修改。这就造成了其他事务在不同的时间点select查看数据库时,会查到不同的数据。这种现象叫不可重复读

        上图可知,只要事务的操作被提交,那么其他事务可以查看到该事务的插入操作,这就会导致其他事务对同一表的查询结果可能会发生变化,这就是不可重复读。

3、可重复读

        可重复读是MySQL默认的隔离级别。

        上图可知,即使事务的操作被提交,其他事务仍然无法查看到该事务对表的操作,只要其他事务也提交以后才能查看到其他事务对表的操作。

4、串行化

        串行化就是对所有事务进行加锁,事务的执行(一般对查询操作不进行加锁)全部挨个排队,这就导致了效率低下问题。

        开启事务A和事务B,两个事务同时select读取将使用共享锁,不会串行化;事务A中有更新等操作,会阻塞A,直到事务B提交。如果事务A阻塞时间过长,将会由于锁等待超时退出当前事务。

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

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

相关文章

视觉分析明火检测助力山东化工厂火情防控

视觉分析技术赋能化工厂火情防控:从山东事故看明火与烟雾检测的应用价值 一、背景:山东化工事故中的火情防控痛点 近期,山东高密友道化学有限公司、淄博润兴化工科技有限公司等企业接连发生爆炸事故,暴露出传统火情防控手段的局…

【小程序】微信小程序备案失败,有请DeepSeek闪亮出场,看TA如何快速给出解决方案

🌹欢迎来到《小5讲堂》🌹 🌹这是《小程序》系列文章,每篇文章将以博主理解的角度展开讲解。🌹 🌹温馨提示:博主能力有限,理解水平有限,若有不对之处望指正!&a…

Oracle正则表达式学习

目录 一、正则表达简介 二、REGEXP_LIKE(x,匹配项) 三、REGEXP_INSTR 四、REGEXP_SUBSTR 五、REGEXP_REPLACE 一、正则表达简介 相关网址: https://cloud.tencent.com/developer/article/1456428 https://www.cnblogs.com/lxl57610/p/8227599.html https://…

vscode 代理模式(agent mode),简单尝试一下。

1. 起因, 目的: agent mode, 很流行,名气很大。简单试试效果,确实很强。agent mode, 取代人工,确实是前进了一大步。 2. 先看效果 效果对比,左边是 普通的AI 生成的, 右边是 代理…

贝锐蒲公英工业路由器R300A海外版:支持多国4G频段,全球组网

为更好地满足全球部署和企业出海项目的多样化需求,贝锐蒲公英异地组网工业路由器R300A海外版全新上市,并已正式上架速卖通!无论是跨国分支机构协同办公,还是海外工厂设备远程运维,R300A海外版都能为企业提供灵活、高性…

自然图像数据集

目录 CIFAR-10 数据集CIFAR-100 数据集AFHQ 数据集FFHQ 数据集 CIFAR-10 数据集 简介: CIFAR-10 是一个经典的图像分类数据集,广泛用于机器学习领域的计算机视觉算法基准测试。它包含60000幅32x32的彩色图像,分为10个类,每类6000…

【AI面试秘籍】| 第25期:RAG的关键痛点及解决方案深度解析

今天我们来聊聊大模型领域一个非常火热的技术——RAG(Retrieval Augmented Generation)。RAG通过引入外部知识库,有效地缓解了大型语言模型(LLM)在处理知识密集型任务时可能出现的幻觉、知识过时等问题。然而&#xff…

精英-探索双群协同优化(Elite-Exploration Dual Swarm Cooperative Optimization, EEDSCO)

一种多群体智能优化算法,其核心思想是通过两个分工明确的群体——精英群和探索群——协同工作,平衡算法的全局探索与局部开发能力,从而提高收敛精度并避免早熟收敛。 一 核心概念 在传统优化算法(如粒子群优化、遗传算法&#xf…

Transformer相关

问题汇总 Transformer的结构自注意力机制(Self-Attention)多头自注意力前馈神经网络(Feed-Forward Network, FFN)位置编码编码器(Encoder)和解码器(Decoder)Multi-Query Attention(多查询注意力机制)Grouped-query Attention(分组查询注意力机制)FlashAttention与注…

【位运算】两整数之和(medium)

两整数之和(medium) 题⽬描述:解法(位运算):代码复杂度分析 题⽬链接: 371. 两整数之和 题⽬描述: 给你两个整数 a 和 b ,不使⽤ 运算符 和 - ,计算并返回两…

现代密码学入门 | 现代密码学核心特点介绍

在当今互联互通的世界中,数字数据在全球范围内不断流动,安全通信和数据保护的需求从未如此迫切。现代密码学作为数字防御的先锋,提供了一系列复杂的技术和算法,以保护信息免受窥探和恶意行为的侵害。 现代密码学是从其古典前身—…

Redis分布式锁深度解析与最佳实践

1 2 Redis分布式锁实现方式确实是经典问题,下面我将系统性地分析这个方案及其演进过程,并给出生产级的解决方案。 一、基础方案及其缺陷 1. 初始实现方式 SETNX lock_key unique_value # 尝试获取锁 EXPIRE lock_key 30 # 设置过期时间 …

Hive自定义函数案例(UDF、UDAF、UDTF)

目录 前提条件 背景 概念及适用场景 UDF(User-Defined Function) 概念 适用场景 UDAF(User-Defined Aggregate Function) 概念 适用场景 UDTF(User-Defined Table-Generating Function) 概念 适…

Go语言的原子操作

当我们想要对某个变量并发安全的修改,除了使用官方提供的mutex,还可以使用sync/atomic包的原子操作,它能够保证对变量的读取或修改期间不被其他的协程所影响。 Golang提供的原子操作都是非侵入式的,由标准库sync/atmoic包提供&am…

QNAP MEMOS 域名访问 SSL(Lucky)

注意:下述是通过ssh、docker-compose方式安装docker的,不是直接在container station中安装的哈!!! 一、编辑docker-compose.yml文件 用“#”号标识的,在保存文件的时候建议去掉,不然有时候会出…

C#实现远程锁屏

前言 这是一次提前下班没有锁屏进而引发的一次思考后的产物,思考的主要场景是当人离开电脑后,怎么能控制电脑锁屏,避免屏幕上的聊天记录被曝光。 首先想到通过系统的电源计划设置闲置超时时间熄屏,这可能是最接近场景的解决方案&a…

[Protobuf]常见数据类型以及使用注意事项

[Protobuf]常见数据类型以及使用注意事项 水墨不写bug 文章目录 一、基本数据类型1、字段2、字段的修饰规则 二、自定义数据类型1、message类型2、enum类型3、Any类型4、oneof类型5、map类型 三、小工具1.hexdump2.decode 四、注意事项 一、基本数据类型 protobuf 支持多种基础…

JS分支和循环

程序的执行顺序 在程序开发中&#xff0c;程序有三种不同的执行顺序 1.顺序执行 2.分支执行 3.循环执行 程序的代码块 <script>//一个代码块{var num11var num22var num3num1num2}//一个休想var info{name:"chen",age:18} 1.if分支语句&#xff08;单分支语句&…

Android 开发 Kotlin 全局大喇叭与广播机制

在 Android 开发中&#xff0c;广播机制就像一个神通广大的 “消息快递员”&#xff0c;承担着在不同组件间传递信息的重任。Kotlin 语言的简洁优雅更使其在广播机制的应用中大放异彩。今天&#xff0c;就让我们一同深入探索 Android 开发中 Kotlin 全局大喇叭与广播机制的奥秘…

rabbitmq AI复习

RabbitMq rabbitmq &#x1f9d1;‍&#x1f4bb; User 帮我复习rabbitmq相关知识&#xff0c;我是一个经验丰富的程序员 &#x1f916; Assistant 好的&#xff01;很高兴能通过这种方式帮你复习或学习 RabbitMQ 的知识。按照你说的流程&#xff0c;我们从完全零基础开始&…