《MySQL 事务深度解析:从 ACID 到实战,守住数据一致性的最后防线》

《MySQL 事务深度解析:从 ACID 到实战,守住数据一致性的最后防线》
前引:数据是业务的核心,而事务是数据可靠性的 “守护神”。在 MySQL 中,事务看似简单的 “提交 / 回滚” 操作,背后藏着 ACID 特性的严格约束、隔离级别的底层实现,以及并发场景下的锁竞争逻辑。很多开发者因为一知半解,导致系统出现脏读、幻读、数据丢失等严重问题。今天,我们就来层层拆解 MySQL 事务,让你从 “会用” 到 “精通”,真正守住数据一致性的底线!

目录

【一】事务介绍

【二】为什么要有事务

【三】事务的版本支持

【四】事务提交的两种方式

【五】事务的几种操作

(1)开始一个事务

(2)创建一个保存点

(3)回滚到指定保存点

(4)正常结束一个事务

(5)异常结束一个事务

【六】事务隔离级别

【七】事务相关结论

【八】修改事务隔离级别

【九】客户端会话与事务关系

【十】进阶:数据并发的场景

读-写


【一】事务介绍

事务是一组DML相关的语句(操作指令)集合,这些指令要么成功/不成功,满足如下性质:

原子性(Atomicity):操作不可分割,要么全成要么全败一致性(Consistency):事务前后数据库完整性不被破坏隔离性(Isolation):并发事务互不干扰,避免脏读、幻读等问题持久性(Durability):事务提交后,数据修改永久有效

【二】为什么要有事务

事务是为了服务应用层而存在,数据库是存储数据的地方,那么应用层对数据进行的操作就必须保障数据的一致性,这些关心事情(比如我这次的修改数据会不会不成功、等下有没有可能就没有了)应该人性化的交给MySQL自己实现,因此它是一个服务机制(为应用层服务)

【三】事务的版本支持

在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务, MyISAM 不支持

mysql> show engines;           -- 表格显示 mysql> show engines \G         -- 行显示

【四】事务提交的两种方式

事务的提交方式常见的有两种: 自动提交 和 手动提交

查看事务提交方式:

show variables like 'autocommit';

用 SET 来改变 MySQL 的自动提交模式:

SET AUTOCOMMIT=0;            #SET AUTOCOMMIT=0 禁止自动提交 SET AUTOCOMMIT=1;           #SET AUTOCOMMIT=1 开启自动提交 

【五】事务的几种操作

(1)开始一个事务
begin;
(2)创建一个保存点
savepoint 自命名;
(3)回滚到指定保存点
rollback to 保存点名字;
(4)正常结束一个事务

注意:正常结束一个事务后,不支持回滚

commit;
(5)异常结束一个事务

注意:异常结束自动回滚,由于原子性,自动回到事务未提交时的数据状态

Aborted;

【六】事务隔离级别

(1)读未提交:在该隔离级别,所有的事务都可以看到其他事务没有提交的 执行结果。(实际生产中不可能使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多 并发问题,如脏读,幻读,不可重复读等!

理解:假设多个客户端并发访问操作同一个数据,单个客户端的任何操作不管提交与否,其它人都看的到

总结:不管对方提交与否,都看得到数据的修改

(2)读提交:该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默 认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别会引起不可重复读,即一个事务执行时,如果多次 select, 可能得到不同的结果!

理解:假设A在操作一个事务,B也在操作一个事务

A和B都在修改表1,A在执行commit之前,B是看不到A做出的修改的

一但A做出了提交,B就可以看到A的修改

总结:只要对方提交了,哪怕是多个事务,数据修改就会被其它人看到

(3)可重复读:这是 MySQL 默认的隔离级别,它确保同一个事务,在执行中,多次读取操作数据时,会看到同样的数据行。但是会有幻读问题!

理解:假设A在操作一个事务,B也在操作一个事务

A和B如果操作同一个表,此时A完成了提交,B是看不到修改的,B看到的是B进入该事务开始时的数据,如果A退出事务了,那么B的数据就会更新到最新的

总结:只有单方提交且退出事务,对方才看得到更改

什么是幻读?假设A修改了张三的年龄,然后提交退出事务,B此时可能在筛选年龄时出现两个张三,因为A提交且退出事务了,B就会更新数据

(4)串行化:这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突, 从而解决了幻读的问题。它在每个读的数据行上面加上共享锁!

总结:一把锁,你访问数据是没有问题的,当你修改数据时,只有在你前一个事务修改完了你才可以执行修改的操作,即串行化,唯一就是效率低

【七】事务相关结论

(1)持久化保障:只要开始一个事务,输入begin或者start transaction,事务便必须要通过                   commit提交,才会持久化,与是否设置自动提交无关

(2)事务可以手动回滚,同时,当操作异常,MySQL会自动回滚

以上可以看出事务的原子性和持久性:要么成功要么不成功,数据一经提交,就是持久化

而原子性保障了数据的一致性,

【八】修改事务隔离级别

  • 读未提交SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
  • 读提交SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
  • 可重复读(默认):SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
  • 串行化SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

【九】客户端会话与事务关系

客户端会话并非是一个事务,一个客户端中可以允许多个事务,事务之前相互独立

【十】进阶:数据并发的场景

数据并发场景有以下三种:

读-读 :不存在任何问题,也不需要并发控制

读-写 :有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读

写-写 :有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失

什么是读and读?读写、写写就自然明白了

多个用户访问同一块数据不存在安全问题,因为只访问不修改

读-写

用来解决读-写的方案:多版本并发控制( MVCC )(无锁并发控制)

解决问题:读写互不阻塞

如何解决?超易懂版本

MVCC依靠三个工具:

(1)数据的额外三个标签:最近修改的事务ID、回滚指针、隐式主键

(2)快照仓库(针对写操作):当修改数据时会保存一份原始数据在 undo 日志里面,回滚指针                                                       指向该原始数据

(3)读视图(针对读操作):形成读视图,给当前事务划分可见范围,看不到未提交的或者在你                                                   后面提交的数据版本

运行过程:当A去修改数据时,会加行锁(保证修改的原子性),先将原始数据放在 undo 仓库,如果有读端访问,访问的是 undo 仓库里面的,看不到A的修改,因为有视图范围,读写可以同时进行,视图通过划分范围可以自行屏蔽脏读——四种隔离性无非是对这三个工具“度”的把控

Read more

anaconda添加到环境变量的意义,以及与其捆绑安装的python是否有必要单独添加环境变量。

Anaconda环境变量配置核心解答:意义+Python路径是否需单独配置 一、问题背景 很多新手配置Anaconda环境时,都会纠结两个核心问题: 1. 把Anaconda添加到环境变量到底有什么用? 2. Anaconda捆绑安装的Python(比如3.12.7),需要单独配置环境变量吗? 本文结合实操经验,用通俗的逻辑讲清楚这两个问题,帮大家避坑。 二、Anaconda添加到环境变量的核心意义 环境变量(尤其是PATH变量)的本质是:告诉系统“去哪里找可执行文件(比如python.exe、conda.exe)”。把Anaconda加入环境变量,核心价值有3点: 1. 全局可调用conda/pip/python命令 不加环境变量时:你只能在Anaconda安装目录的Scripts文件夹下执行conda/pip/python命令,比如要切换到D:\Anaconda3\Scripts才能用conda --version;比如要切换到D:\Anaconda3才能用python --version 添加环境变量后:在任意CMD/终端窗口(不管当前路径在哪)

By Ne0inhk
华为OD机试双机位C卷 - Alice的安全旅行 (C++ & JAVA & Python & C语言 & JS & GO)

华为OD机试双机位C卷 - Alice的安全旅行 (C++ & JAVA & Python & C语言 & JS & GO)

Alice的安全旅行 华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 200分题型 华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录|机考题库 + 算法考点详解 题目描述 Alice计划从城市0出发最终到达城市N-1,他可以选择一条路线,但路上经过的城市总数(包括起点和终点)不能超过K个,每个城市都有一个安全度值,整个旅程的安全度被定义为路径上所有城市安全度的最小值,她的目标是让这个最小值尽可能高,请问Alice的旅程总体安全度最大能为多少? 输入描述 第一行有两个整数N和K,表示一共N个城市,以及Alice最多去K个城市(2<N<100000,1<K<100000) 接下来N行 每行包括一个整数h 表示去某个城市的安全度0=<h<=1000000000 接下来一行有一个整数M,表示城市间的M条道路,0<M<200000 接下来M行 每行有两个整数s0 s1

By Ne0inhk
解决“uv 无法识别为命令”问题:Windows 下 Python 工具安装后的路径配置方法

解决“uv 无法识别为命令”问题:Windows 下 Python 工具安装后的路径配置方法

目录 🚀解决“uv 无法识别为命令”问题:Windows 下 Python 工具安装后的路径配置方法 📌问题背景 ✅ 一、确认 uv 是否已安装 ✅ 二、临时使用 uv(快速绕过) ✅ 三、永久解决:将 uv 加入系统环境变量 步骤如下: 🔁 四、可选:为 uv 设置 PowerShell 别名 🧩 总结 📎附录:常见 Python 工具路径(以 Python 3.11 为例) 🚀解决“uv 无法识别为命令”问题:Windows 下 Python 工具安装后的路径配置方法 📌问题背景

By Ne0inhk
【C++:多态】C++多态实现深度剖析:从抽象类约束到虚函数表机制

【C++:多态】C++多态实现深度剖析:从抽象类约束到虚函数表机制

🔥艾莉丝努力练剑:个人主页 ❄专栏传送门:《C语言》、《数据结构与算法》、C/C++干货分享&学习过程记录、Linux操作系统编程详解、笔试/面试常见算法:从基础到进阶 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬艾莉丝的简介: 🎬艾莉丝的C++专栏简介: 目录 本文内容索引 C++的两个参考文档 3  ~>   纯虚函数与抽象类:从语法规范到底层约束 3.1  纯虚函数的语法语义深度解析 3.2  抽象类的设计意义与使用场景 3.3  实践验证:抽象类实例化的编译器级限制 3.3.1   分析:抽象类实例化编译错误 3.3.2  对象实例化条件验证 3.3.

By Ne0inhk