【MySQL】事务及隔离性
目录
一、什么是事务
(一)概念
(二)事务的四大属性
(三)事务的作用
(四)事务的提交方式
二、事务的启动、回滚与提交
(一)事务的启动、回滚与提交
(二)特殊情况
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、读未提交
在多个并行的会话中启动事务,一个事务在改动数据库哪怕没有commit提交,其他事务也是能够实时的看到它修改的数据。一个事务在执行中,读到另一个执行中事务的更新(或其他操作)但是未commit的数据,这种不合理的现象叫做脏读(dirty read)。
上图可以看出,即使左端事务没有进行提交操作,但右端事务仍可以看到表的操作,这就是脏读。
2、读已提交
事务A在commit提交事务之前,所做的修改是不会被其他事务看到的,一旦事务A发起commit之后,其他事务就能看到事务A对数据的修改。这就造成了其他事务在不同的时间点select查看数据库时,会查到不同的数据。这种现象叫不可重复读。
上图可知,只要事务的操作被提交,那么其他事务可以查看到该事务的插入操作,这就会导致其他事务对同一表的查询结果可能会发生变化,这就是不可重复读。
3、可重复读
可重复读是MySQL默认的隔离级别。
上图可知,即使事务的操作被提交,其他事务仍然无法查看到该事务对表的操作,只要其他事务也提交以后才能查看到其他事务对表的操作。
4、串行化
串行化就是对所有事务进行加锁,事务的执行(一般对查询操作不进行加锁)全部挨个排队,这就导致了效率低下问题。
开启事务A和事务B,两个事务同时select读取将使用共享锁,不会串行化;事务A中有更新等操作,会阻塞A,直到事务B提交。如果事务A阻塞时间过长,将会由于锁等待超时退出当前事务。
相关文章:

【MySQL】事务及隔离性
目录 一、什么是事务 (一)概念 (二)事务的四大属性 (三)事务的作用 (四)事务的提交方式 二、事务的启动、回滚与提交 (一)事务的启动、回滚与提交 &am…...
Leetcode 3566. Partition Array into Two Equal Product Subsets
Leetcode 3566. Partition Array into Two Equal Product Subsets 1. 解题思路2. 代码实现 题目链接:3566. Partition Array into Two Equal Product Subsets 1. 解题思路 这一题我的实现还是比较暴力的,首先显而易见的,若要满足题目要求&…...

yolo目标检测助手:具有模型预测、图像标注功能
在人工智能浪潮席卷各行各业的今天,计算机视觉模型(如 YOLO)已成为目标检测领域的标杆。然而,模型的强大能力需要直观的界面和便捷的工具才能充分发挥其演示、验证与迭代优化的价值。为此,我开发了一款基于 WPF 的桌面…...
传统数据表设计与Prompt驱动设计的范式对比:以NBA投篮数据表为例
引言:数据表设计方法的演进 在数据库设计领域,传统的数据表设计方法与新兴的Prompt驱动设计方法代表了两种截然不同的思维方式。本文将以NBA赛季投篮数据表(shots)的设计为例,深入探讨这两种方法的差异、优劣及适用场景。随着AI技术在数据领…...

2022 RoboCom 世界机器人开发者大赛(睿抗 caip) -高职组(国赛)解题报告 | 科学家
前言 题解 2022 RoboCom 世界机器人开发者大赛(睿抗 caip) -高职组(国赛)。 最后一题还考验能力,需要找到合适的剪枝。 RC-v1 智能管家 分值: 20分 签到题,map的简单实用 #include <bits/stdc.h>using namespace std;int…...
WIN11 Docker Desktop 安装问题解决
windows version 打开windows 命令行,执行 ver显示 Microsoft Windows [版本 10.0.26100.4061]安装docker desktop 后,启动出问题,可以按下面步骤解决 安装 virtual machine plateform 开始 —》 控制面板 ----》程序 ----》启动或关闭w…...
网站服务器出现异常的原因是什么?
网站时企业和个人用户进行提供信息和服务的重要平台,随着时间的推移,网站服务器出现异常情况也是常见的问题之一,这可能会导致网站无法正常访问或者是运行缓慢,会严重影响到用户的体验感,本文就来介绍一下网站服务器出…...
Python实例题:Python3实现图片转彩色字符
目录 Python实例题 题目 代码实现 实现原理 图像预处理: 灰度值计算: 字符映射: 彩色输出: 关键代码解析 1. 字符映射和灰度计算 2. 图像模式输出 3. 命令行参数处理 使用说明 基本用法(终端输出&#x…...
同一机器下通过HTTP域名访问其他服务器进程返回504问题记录
我这边项目的服务器有好几个类型节点,每个节点为一个进程,不同节点间通过HTTP来通讯,当前这几个类型的节点都部署在同一台机器上,然后我再测试某个节点到另一个节点的http通讯时,发现一个奇怪的现象: 1. 我…...

基于物联网(IoT)的电动汽车(EVs)智能诊断
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从&#x…...

JDBC+HTML+AJAX实现登陆和单表的CRUD
JDBCHTMLAJAX实现登陆和单表的CRUD 导入maven依赖 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocatio…...
Leetcode 3568. Minimum Moves to Clean the Classroom
Leetcode 3568. Minimum Moves to Clean the Classroom 1. 解题思路2. 代码实现 题目链接:3568. Minimum Moves to Clean the Classroom 1. 解题思路 这一题我的核心思路就是广度优先遍历遍历剪枝。 显然,我们可以给出一个广度优先遍历来给出所有可能…...
Kafka多线程Consumer
Apache Kafka作为一款分布式流处理平台,以其高吞吐量和可扩展性在大数据处理领域占据了重要地位。在实际应用中,为了提升数据处理的效率和灵活性,我们常常需要采用多线程的方式来消费Kafka中的数据。本文将通过一个案例分析,详细探…...
从零开始的git学习
基本概念:修改记录 1、每个修改记录都有对应的id 2、当发现修改有问题时,可以进行回滚操作。 3、回滚的本质是一次新的更新以复原修改。但是如果不是针对最新记录进行回滚,会出现冲突。 这里需要举例说明 基本概念:分支 1、分支…...

【C++】位图详解(一文彻底搞懂位图的使用方法与底层原理)
🌈 个人主页:谁在夜里看海. 🔥 个人专栏:《C系列》《Linux系列》 ⛰️ 天高地阔,欲往观之。 目录 1.位图的概念 2.位图的使用方法 定义与创建 设置和清除 位访问和检查 转换为其他格式 3.位图的使用场景 1.快速…...
Spring Boot 整合 JdbcTemplate,JdbcTemplate 与 MyBatis 的区别
DAY29.1 Java核心基础 Spring Boot 整合 JdbcTemplate JdbcTemplate是一个轻量级JDBC封装的组件 JdbcTemplate 是 Spring 自带的JDBC的封装,和Mybatis类似,需要自己封装sql语句 JdbcTemplate 帮助我们来连接数据库,SQL的执行,…...
sass基础语法
Sass(Syntactically Awesome Style Sheets)是一种 CSS 预处理器,提供了比原生 CSS 更强大、更灵活的语法功能。它有两种语法格式: Sass(缩进语法,.sass 文件)SCSS(CSS-like 语法&am…...
【EF Core】 EF Core 批量操作的进化之路——从传统变更跟踪到无跟踪更新
文章目录 前言一、批量操作(Rang)1.1 AddRange()1.2 UpdateRange()1.3 AttachRange()1.4 RemoveRange() 二、Range操作的底层优化2.1 EF Core 7 前举步维艰2.2 EF Core 7后焕然一新 三、无跟踪的批量更新与删除3.1 ExecuteUpdate3.2 ExecuteDelete3.3 状…...
[Go] Option选项设计模式 — — 编程方式基础入门
[Go] Option选项设计模式 — — 编程方式基础入门 全部代码地址,欢迎⭐️ Github:https://github.com/ziyifast/ziyifast-code_instruction/tree/main/go-demo/go-option 1 介绍 在 Go 开发中,我们经常遇到需要处理多参数配置的场景。传统方…...
Vue 项目命名规范指南
📚 Vue 项目命名规范指南(适用于 Vue 3 Pinia Vue Router) 目的:统一命名风格,提升可读性、可维护性和团队协作效率。 一、通用原则 类型命名风格示例变量camelCaseuserName, isLoading常量UPPER_SNAKE_CASEMAX_RET…...

【笔记】开源通用人工智能代理 Suna 部署全流程准备清单(Windows 系统)
#工作记录 一、基础工具与环境 开发工具 Git 或 GitHub Desktop(代码管理)Docker Desktop(需启用 WSL2,容器化部署)Python 3.11(推荐版本,需添加到系统环境变量)Node.js LTS…...

海康工业相机SDK二次开发(VS+QT+海康SDK+C++)
前言 工业相机在现代制造和工业自动化中扮演了至关重要的角色,尤其是在高精度、高速度检测中。海康威视工业相机以其性能稳定、图像质量高、兼容性强而受到广泛青睐。特别是搞机器视觉的小伙伴们跟海康打交道肯定不在少数,笔者在平常项目中跟海康相关人…...
前端面试准备-5
1.Node.js中的process.nectTick()有什么作用 将一个回调函数插入到当前执行栈的尾部,在下一次事件轮询之前调用这个回调函数 2.什么是Node.js中的事件发射器,作用是什么,如何使用 提供一种机制,可以创建、触发和监听自定义事件…...
Spring Boot 启动流程深度解析:从源码到实践
Spring Boot 启动流程深度解析:从源码到实践 Spring Boot 作为 Java 开发的主流框架,其 “约定大于配置” 的理念极大提升了开发效率。本文将从源码层面深入解析 Spring Boot 的启动流程,并通过代码示例展示其工作机制。 一、Spring Boot 启…...

深度学习|pytorch基本运算-乘除法和幂运算
【1】引言 前序学习进程中,已经对pytorch张量数据的生成和广播做了详细探究,文章链接为: 深度学习|pytorch基本运算-CSDN博客 深度学习|pytorch基本运算-广播失效-CSDN博客 上述探索的内容还止步于张量的加减法,在此基础上&am…...
嵌入式通用集成电路卡市场潜力报告:物联网浪潮下的机遇与挑战剖析
一、嵌入式通用集成电路卡概述 嵌入式通用集成电路卡(Embedded Universal Integrated Circuit Card,简称 eUICC),是一种将传统 SIM 卡功能直接嵌入到设备主板上的芯片解决方案 。与传统可插拔式 SIM 卡不同,eUICC 采…...

4.2.4 Spark SQL 数据写入模式
在本节实战中,我们详细探讨了Spark SQL中数据写入的四种模式:ErrorIfExists、Append、Overwrite和Ignore。通过具体案例,我们演示了如何使用mode()方法结合SaveMode枚举类来控制数据写入行为。我们首先读取了一个JSON文件生成DataFrame&#…...

论文笔记: Urban Region Embedding via Multi-View Contrastive Prediction
AAAI 2024 1 INTRO 之前基于多视图的region embedding工作大多遵循相同的模式 单独的单视图表示多视图融合 但这种方法存在明显的局限性:忽略了不同视图之间的信息一致性 一个区域的多个视图所携带的信息是高度相关的,因此它们的表示应该是一致的如果能…...
Android 缓存应用冻结器(Cached Apps Freezer)
一、核心功能与原理 1. 功能概述 目标:通过冻结后台缓存应用的进程,减少其对 CPU、内存等系统资源的消耗,优化设备性能与续航。适用场景:针对行为不当的后台应用(如后台偷偷运行代码、占用 CPU)ÿ…...

初学者如何微调大模型?从0到1详解
本文将手把手带你从0到1,详细解析初学者如何微调大模型,让你也能驾驭这些强大的AI工具。 1. 什么是大模型微调? 想象一下,预训练大模型就像一位博览群书但缺乏专业知识的通才。它掌握了海量的通用知识,但可能无法完美…...