【MYSQL】MYSQL学习的一大重点:事务(上)- 原子性与持久性

🎬 个人主页艾莉丝努力练剑
专栏传送门 :《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录
Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬 艾莉丝的简介:


文章目录

  • [1 ~> 事务基础理论](#1 ~> 事务基础理论)
    • [1.1 事务的定义](#1.1 事务的定义)
    • [1.2 设计背景与核心价值](#1.2 设计背景与核心价值)
      • [1.2.1 并发无控制的典型问题](#1.2.1 并发无控制的典型问题)
      • [1.2.2 事务的核心价值](#1.2.2 事务的核心价值)
    • [1.3 ACID 四大特性](#1.3 ACID 四大特性)
      • [1.3.1 原子性(Atomicity)](#1.3.1 原子性(Atomicity))
      • [1.3.2 一致性(Consistency)](#1.3.2 一致性(Consistency))
      • [1.3.3 隔离性(Isolation)](#1.3.3 隔离性(Isolation))
      • [1.3.4 持久性(Durability)](#1.3.4 持久性(Durability))
  • [2 ~> MySQL 事务支持机制](#2 ~> MySQL 事务支持机制)
    • [2.1 存储引擎支持](#2.1 存储引擎支持)
      • [2.1.1 查看引擎事务支持](#2.1.1 查看引擎事务支持)
    • [2.2 事务提交模式](#2.2 事务提交模式)
      • [2.2.1 两种提交模式](#2.2.1 两种提交模式)
      • [2.2.2 提交模式操作语法](#2.2.2 提交模式操作语法)
      • [2.2.3 核心结论](#2.2.3 核心结论)
  • [3 ~> 事务标准操作](#3 ~> 事务标准操作)
    • [3.1 实验环境准备](#3.1 实验环境准备)
      • [3.1.1 创建测试表](#3.1.1 创建测试表)
      • [3.1.2 设置隔离级别(实验专用)](#3.1.2 设置隔离级别(实验专用))
    • [3.2 核心操作语法](#3.2 核心操作语法)
      • [3.2.1 开启事务](#3.2.1 开启事务)
      • [3.2.2 设置保存点](#3.2.2 设置保存点)
      • [3.2.3 事务回滚](#3.2.3 事务回滚)
      • [3.2.4 提交事务](#3.2.4 提交事务)
    • [3.3 操作约束](#3.3 操作约束)
  • [4 ~> 核心特性实验验证](#4 ~> 核心特性实验验证)
    • [4.1 原子性验证](#4.1 原子性验证)
      • [4.1.1 场景 1:未提交事务客户端异常崩溃](#4.1.1 场景 1:未提交事务客户端异常崩溃)
      • [4.1.2 场景 2:保存点定向回滚](#4.1.2 场景 2:保存点定向回滚)
    • [4.2 持久性验证](#4.2 持久性验证)
      • [4.2.1 场景:已提交事务客户端崩溃](#4.2.1 场景:已提交事务客户端崩溃)
    • [4.3 单条 SQL 与事务的关系](#4.3 单条 SQL 与事务的关系)
      • [4.3.1 核心结论](#4.3.1 核心结论)
      • [4.3.2 对照验证](#4.3.2 对照验证)
  • [5 ~> 事务隔离级别入门](#5 ~> 事务隔离级别入门)
    • [5.1 基本概念](#5.1 基本概念)
    • [5.2 四大隔离级别](#5.2 四大隔离级别)
      • [5.2.1 读未提交(Read Uncommitted)](#5.2.1 读未提交(Read Uncommitted))
      • [5.2.2 读已提交(Read Committed)](#5.2.2 读已提交(Read Committed))
      • [5.2.3 可重复读(Repeatable Read)](#5.2.3 可重复读(Repeatable Read))
      • [5.2.4 串行化(Serializable)](#5.2.4 串行化(Serializable))
  • [6 ~> 技术审计与勘误汇总](#6 ~> 技术审计与勘误汇总)
    • [6.1 概念性错误修正](#6.1 概念性错误修正)
    • [6.2 拼写与笔误修正](#6.2 拼写与笔误修正)
    • [6.3 表述准确性修正](#6.3 表述准确性修正)
    • [6.4 版本兼容性提示](#6.4 版本兼容性提示)
  • 结尾


1 ~> 事务基础理论

1.1 事务的定义

事务是由一条或多条逻辑相关的 DML 语句组成的执行集合,该集合作为不可分割的整体,要么全部执行成功,要么全部执行失败并回滚,对外呈现原子性的执行效果。

  • 业务视角:将上层业务的一个完整操作(如转账、购票)映射为一组 SQL,共同完成业务目标,单条 SQL 脱离集合无独立业务意义。
  • 数据库视角:MySQL 将一组 SQL 封装为事务对象进行调度管理,保障并发场景下的数据正确性。

1.2 设计背景与核心价值

1.2.1 并发无控制的典型问题

无事务保障的并发 CURD 会直接破坏数据一致性,典型场景:

  1. 售票超卖:多客户端同时读取库存为 1,并发执行扣减,最终同一张票被售卖两次。
  2. 转账异常:扣款操作执行后服务宕机,收款方未到账,数据库出现金额不守恒的中间状态。

1.2.2 事务的核心价值

事务本质是为应用层服务,将并发控制、故障容错能力下沉到数据库层:

  • 上层应用无需关心网络异常、服务宕机、并发冲突等底层问题。
  • 仅需关注业务逻辑,通过提交 / 回滚即可保障数据正确性,大幅简化编程模型。

1.3 ACID 四大特性

1.3.1 原子性(Atomicity)

事务是不可分割的最小执行单元,所有操作要么全部完成,要么全部回滚到事务开始前的状态,不存在部分执行的中间状态。

  • 实现依托:回滚机制(rollback),事务执行异常时自动撤销已执行的所有操作。

1.3.2 一致性(Consistency)

事务执行前后,数据库的完整性约束不被破坏,数据始终符合预设的业务规则(如账户余额总和不变、库存非负、主键唯一)。

  • 关键说明:一致性是事务的最终目标,数据库通过原子性、隔离性、持久性共同保障一致性;同时一致性依赖上层业务逻辑的正确性,仅靠数据库无法完全保证。

1.3.3 隔离性(Isolation)

数据库支持多事务并发执行,隔离性保障多个事务交叉执行时,不会因互相干扰导致数据不一致。

  • 隔离性通过不同的隔离级别实现,不同级别对应不同的并发干扰程度与性能表现。

1.3.4 持久性(Durability)

事务一旦提交(commit),对数据的修改就会永久持久化到磁盘,后续即使系统宕机、服务重启,已提交的数据也不会丢失。


2 ~> MySQL 事务支持机制

2.1 存储引擎支持

MySQL 的事务能力由存储引擎层实现,并非所有引擎都支持事务:

  • InnoDB:MySQL 默认存储引擎,完整支持事务、行级锁、外键,同时支持保存点、XA 分布式事务。
  • MyISAM、MEMORY、BLACKHOLE、CSV、ARCHIVE:均不支持事务。

2.1.1 查看引擎事务支持

sql 复制代码
-- 横向展示所有引擎信息
SHOW ENGINES;

-- 纵向展示,便于阅读
SHOW ENGINES \G

2.2 事务提交模式

2.2.1 两种提交模式

  1. 自动提交(autocommit = ON):MySQL 默认模式,单条 SQL 执行完成后自动提交事务,用户无感知。
  2. 手动提交 :通过begin显式开启事务,必须执行commit才会提交,执行rollback则回滚。

2.2.2 提交模式操作语法

sql 复制代码
-- 查看当前自动提交状态
SHOW VARIABLES LIKE 'autocommit';

-- 关闭自动提交
SET AUTOCOMMIT = 0;

-- 开启自动提交
SET AUTOCOMMIT = 1;

2.2.3 核心结论

  • 显式通过begin/start transaction开启的事务,不受 autocommit 配置影响,必须手动 commit 才会提交。
  • 未显式开启事务时,单条 SQL 的行为由 autocommit 决定:autocommit=ON 则自动提交,autocommit=OFF 则需手动提交。

3 ~> 事务标准操作

3.1 实验环境准备

3.1.1 创建测试表

sql 复制代码
CREATE TABLE IF NOT EXISTS account (
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL DEFAULT '',
    balance DECIMAL(10,2) NOT NULL DEFAULT 0.0  -- 原笔记blance为笔误,修正为balance
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3.1.2 设置隔离级别(实验专用)

为便于观察并发现象,实验中将隔离级别设置为最低的读未提交:

sql 复制代码
-- 设置全局事务隔离级别为读未提交
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

-- MySQL 5.7 查询当前会话隔离级别
SELECT @@tx_isolation;

-- MySQL 8.0+ 查询当前会话隔离级别(tx_isolation已废弃)
SELECT @@transaction_isolation;

注意:修改全局隔离级别后,需重启客户端会话才会生效。

3.2 核心操作语法

3.2.1 开启事务

两种等价写法:

sql 复制代码
-- 写法1
START TRANSACTION;
-- 写法2(推荐,更简洁)
BEGIN;

3.2.2 设置保存点

用于实现事务内的定向回滚,一个事务可设置多个保存点:

sql 复制代码
SAVEPOINT 保存点名称;
-- 示例
SAVEPOINT s1;

3.2.3 事务回滚

两种回滚粒度:

sql 复制代码
-- 1. 回滚到指定保存点,撤销保存点之后的所有操作
ROLLBACK TO 保存点名称;
-- 示例
ROLLBACK TO s1;

-- 2. 回滚整个事务,撤销事务内所有操作,回到事务初始状态
ROLLBACK;

3.2.4 提交事务

sql 复制代码
COMMIT;

3.3 操作约束

  1. 未设置保存点时,rollback直接回滚到事务开启时的状态。
  2. 事务一旦执行commit提交,就无法再回滚。
  3. 保存点仅在当前事务内有效,事务提交或全量回滚后保存点自动失效。

4 ~> 核心特性实验验证

4.1 原子性验证

4.1.1 场景 1:未提交事务客户端异常崩溃

  • 操作步骤:开启事务 → 执行 INSERT/UPDATE 等 DML → 不执行 commit,直接强制终止客户端进程。
  • 实验现象:重启客户端后查询,数据不存在,MySQL 自动回滚了未提交的事务。
  • 结论:未提交的事务异常终止时,数据库自动回滚所有修改,保障无中间状态,体现原子性。

4.1.2 场景 2:保存点定向回滚

  • 操作步骤:开启事务 → 设置保存点 s1 → 插入数据 → 设置保存点 s2 → 插入第二条数据 → 回滚到 s1。
  • 实验现象:第二条数据被撤销,仅保留 s1 之前的操作。
  • 结论:事务支持粒度化的回滚能力,是原子性的具体实现形式。

4.2 持久性验证

4.2.1 场景:已提交事务客户端崩溃

  • 操作步骤:开启事务 → 执行 DML → 执行 commit 提交 → 强制终止客户端进程。
  • 实验现象:重启客户端后查询,数据依然存在。
  • 结论:事务提交后,修改已持久化到磁盘,客户端崩溃、服务重启都不会丢失数据,体现持久性。

4.3 单条 SQL 与事务的关系

4.3.1 核心结论

InnoDB 中所有 SQL 操作本质都属于事务 ,日常单条 SQL 无事务感知,是因为autocommit=ON时 SQL 执行完自动提交了事务。

4.3.2 对照验证

  1. autocommit = OFF 场景 :执行单条 DELETE 后不 commit,客户端崩溃,数据自动回滚。
    1. 本质:单条 SQL 开启了事务但未提交,异常触发回滚机制。
  2. autocommit = ON 场景 :执行单条 DELETE 后,客户端崩溃,数据已被永久删除。
    1. 本质:单条 SQL 执行完毕后自动提交事务,修改已持久化。

5 ~> 事务隔离级别入门

5.1 基本概念

  • 隔离性:保障多事务并发执行时互不干扰、数据一致的能力。
  • 隔离级别:定义了事务之间的干扰程度,级别越低,并发性能越高,但数据一致性越差。

5.2 四大隔离级别

5.2.1 读未提交(Read Uncommitted)

  • 定义:一个事务可以读取到其他事务未提交的修改结果。
  • 并发问题:脏读、不可重复读、幻读。
  • 应用:生产环境基本不使用,仅用于原理演示实验。

5.2.2 读已提交(Read Committed)

  • 定义:一个事务只能读取到其他事务已经提交的修改。
  • 并发问题:解决了脏读,但存在不可重复读(同一事务内多次 SELECT 同一行,结果不一致)。
  • 应用:大多数数据库的默认隔离级别(如 Oracle、PostgreSQL)。

5.2.3 可重复读(Repeatable Read)

  • 定义:同一事务内,多次读取同一行数据,结果始终一致。
  • 并发问题:解决了脏读、不可重复读,理论上存在幻读;InnoDB 通过 MVCC + 间隙锁在很大程度上解决了幻读问题。
  • 应用:MySQL 的默认隔离级别。

5.2.4 串行化(Serializable)

  • 定义:最高隔离级别,强制事务串行执行,对读取的数据行加共享锁。
  • 并发问题:解决了所有并发异常,但性能极差,会导致大量锁竞争和超时。
  • 应用:生产环境极少使用。

6 ~> 技术审计与勘误汇总

6.1 概念性错误修正

原文错误表述 修正后正确表述
原子性、隔离性、持久性这三个是 "因",原子性是 "果" 原子性、隔离性、持久性这三个是 "因",一致性是 "果";数据库通过实现前三者保障一致性

6.2 拼写与笔误修正

  1. erializableSerializable(串行化英文拼写)
  2. blancebalance(账户余额字段)
  3. MtISAMMyISAM(存储引擎名称)

6.3 表述准确性修正

  • 原文:"对于 InnoDB 每一条 SQL 语言都默认封装成事务,自动提交。(select 有特殊情况,因为 MySQL 有 MVCC)"
  • 修正:InnoDB 中所有单条 SQL 在autocommit=ON时都会被封装为独立事务并自动提交,包含 SELECT 语句。MVCC 是事务隔离的实现机制,并非让 SELECT 脱离事务的原因。

6.4 版本兼容性提示

  • @@tx_isolation 仅适用于 MySQL 5.7 及更早版本,MySQL 8.0 已移除该变量,统一使用 @@transaction_isolation 查询事务隔离级别。

结尾

uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ### 艾莉丝努力练剑 C/C++ & Linux 底层探索者 | 一个正在努力练剑的技术博主 *** ** * ** *** 👀 【关注】 跟随我一起深耕技术领域,见证每一次成长。 ❤️ 【点赞】 让优质内容被更多人看见,让知识传递更有力量。 ⭐ 【收藏】 把核心知识点存好,在需要时随时查、随时用。 💬 【评论】 分享你的经验或疑问,评论区一起交流避坑! 不要忘记给博主"一键四连"哦! "今日练剑达成!" "技术之路难免有困惑,但同行的人会让前进更有方向。" |

结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主"一键四连"哦!

往期回顾

【MYSQL】MYSQL学习的一大重点:索引(下)- B+树

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡 ૮₍ ˶ ˊ ᴥ ˋ˶₎ა

相关推荐
神秘的MT1 小时前
C# WinForm Socket 类 常用方法 (C# .NET,TCP 场景)
服务器·网络·学习·tcp/ip·c#·winform
丶玉面小蛟龙3 小时前
DGCNN网络学习
学习·点云·dgcnn
曹牧3 小时前
Java:BeanListHandler
java·数据库·oracle
ITenderL5 小时前
MySQL联合索引遇到范围查询
数据库·索引
晓梦林9 小时前
BUUCTF findKey-学习笔记
笔记·学习
0566469 小时前
agent学习Day15——SQLAlchemy 查询过滤、分页与历史列表接口
python·学习·fastapi
敲个大西瓜10 小时前
Redis一百道核心面试题
数据库·redis·缓存
炎武丶航11 小时前
汽车功能测试学习(1):FCW前方碰撞预警
功能测试·学习·汽车
plainGeekDev13 小时前
工厂模式 → Hilt
android·java·kotlin