【MySQL 零基础入门】事务精讲(二):ACID 特性与并发问题

是思成呀:个人主页

个人专栏《C++知识总结》《MySQL 零基础入门到实战》


引言

事务之所以能保证数据一致性,核心是靠 ACID 四大特性 "保驾护航"------ 原子性保证操作不可分割,一致性保证数据逻辑无误,隔离性保证多事务互不干扰,持久性保证数据永久保存。而在多事务并发执行时,即使有 ACID,也可能出现脏读、不可重复读、幻读等问题(比如同时给两名高中生缴费导致余额计算错误、查询学生成绩时读到未提交的临时数据)。本文带你吃透 ACID 的底层逻辑,理清并发事务的三大问题,为后续学习隔离级别打下基础!

目录

一、事务的四大特性(ACID)(精简案例解读)

[1. 原子性(Atomicity)](#1. 原子性(Atomicity))

[2. 一致性(Consistency)](#2. 一致性(Consistency))

[3. 隔离性(Isolation)](#3. 隔离性(Isolation))

[4. 持久性(Durability)](#4. 持久性(Durability))

二、并发事务引发的三大问题

[1. 脏读(Dirty Read)](#1. 脏读(Dirty Read))

[2. 不可重复读(Non-Repeatable Read)](#2. 不可重复读(Non-Repeatable Read))

[3. 幻读(Phantom Read)](#3. 幻读(Phantom Read))

三、问题根源与解决思路

结尾


一、事务的四大特性(ACID)(精简案例解读)

ACID 是事务的核心属性,保证了事务的可靠性和数据一致性,精简后 5 名学生的场景更易理解:

1. 原子性(Atomicity)

  • 定义:事务是不可分割的最小操作单元,要么全部执行成功,要么全部失败回滚。
  • 案例:高中生缴费事务中,"扣减林墨涵账户余额" 和 "更新缴费状态" 必须同时成功或同时失败,不会出现中间状态(如余额扣了但状态没更)。
  • 实现原理:MySQL 通过日志(undo log)记录事务的修改操作,回滚时通过日志撤销已执行的操作。

2. 一致性(Consistency)

  • 定义:事务执行前后,数据库的完整性约束(如主键唯一、余额非负)保持不变,数据逻辑一致。
  • 案例:林墨涵缴费前账户余额 2000 元 + 缴费记录状态 "未缴费",缴费后余额 500 元 + 状态 "已缴费",整体数据逻辑无矛盾;若出现余额扣了但状态仍为 "未缴费",则违反一致性。
  • 关键要求:事务必须满足业务规则(如学生余额不能为负),否则即使原子性满足,一致性也会被破坏。

3. 隔离性(Isolation)

  • 定义:多个事务并发执行时,事务之间相互隔离,每个事务感觉不到其他事务的存在。
  • 案例:事务 A 给林墨涵缴费(未提交),事务 B 查询林墨涵余额时,不会看到事务 A 未提交的临时数据(余额仍为 2000 元)。
  • 实现原理:通过锁机制和多版本并发控制(MVCC)实现,避免并发事务相互干扰。

4. 持久性(Durability)

  • 定义:事务一旦提交,对数据的修改会永久保存到数据库(即使服务器崩溃,数据也不会丢失)。
  • 实现原理:MySQL 通过 redo log 记录已提交的修改,崩溃恢复时通过 redo log 重新应用修改,保证数据持久化。
  • 验证方式:事务提交后,数据会写入磁盘的.ibd 文件(InnoDB 数据文件),重启数据库后林墨涵的余额和缴费状态依然是修改后的值。

二、并发事务引发的三大问题

当多个事务同时操作 5 名高中生数据时,若没有合适的隔离机制,会引发以下核心问题:

1. 脏读(Dirty Read)

  • 定义:一个事务读取到另一个事务未提交的数据(临时数据,可能被回滚)。
  • 场景演示
  1. 事务 A 开启,执行 UPDATE student_account SET balance = 500 WHERE student_name = '林墨涵'(未提交);
  2. 事务 B 查询林墨涵的余额,得到 500 元(脏数据);
  3. 事务 A 执行 ROLLBACK,林墨涵余额恢复为 2000 元;
  4. 事务 B 读取的 500 元是无效数据,若基于此判断林墨涵余额不足拒绝缴费,就会导致业务错误。
  • 危害:基于脏数据的决策会导致业务逻辑错误(如误判高中生缴费能力)。

2. 不可重复读(Non-Repeatable Read)

  • 定义:同一事务内多次读取同一数据,结果不一致(其他事务提交了更新操作)。
  • 场景演示(精简版)
  1. 事务 A 开启,首次查询林墨涵余额为 2000 元;
  2. 事务 B 执行 UPDATE student_account SET balance = 500 WHERE student_name = '林墨涵' 并提交;
  3. 事务 A 再次查询林墨涵余额,得到 500 元,与首次结果不一致。
  • 与脏读的区别:不可重复读读取的是已提交的数据,脏读读取的是未提交数据。

3. 幻读(Phantom Read)

  • 定义:同一事务内多次执行相同的范围查询,结果集的行数不一致(其他事务提交了插入 / 删除操作)。
  • 场景演示(精简版)
  1. 事务 A 开启,查询余额 > 2000 的高中生,得到苏语桐、楚泽宇、温知夏 3 人;
  2. 事务 B 插入一条新记录:INSERT INTO student_account(student_name, balance, class_name) VALUES ('江弈辰', 2200, '高一(1)班') 并提交;
  3. 事务 A 再次执行相同查询,得到 4 人,行数增加("幻影" 行出现)。
  • 与不可重复读的区别:不可重复读针对已有数据的修改(如林墨涵余额变化),幻读针对新数据的插入 / 删除(如新增江弈辰的记录)。

三、问题根源与解决思路

并发事务问题的本质是:多个事务同时操作同一高中生数据,且未对数据访问顺序进行有效控制。解决思路:通过设置事务隔离级别,在 "数据一致性" 和 "并发性能" 之间做权衡 ------ 隔离级别越高,数据越安全,但并发性能越低(比如同时缴费的高中生数量会减少)。

结尾

🍍 我是思成!若这篇内容帮你理清了 MySQL 事务 ACID 特性与并发问题的核心逻辑:

👀 【关注】跟我一起拆解 MySQL 核心知识点,从 ACID 特性到隔离级别,吃透每一个事务并发规则

❤️ 【点赞】让技术干货被更多人看见,让抽象的脏读、幻读逻辑变得易懂

⭐ 【收藏】把 ACID 四大特性、高中生数据并发问题案例存好,事务开发 / 面试时随时查阅

💬 【评论】分享你遇到的高中生数据事务并发问题,或想深挖的事务知识点,一起交流进步

🗳️ 【投票】告诉我你最想拆解的下一个知识点(比如事务隔离级别?锁机制?)

技术学习没有捷径,但找对思路能少走弯路~愿我们都能把抽象的事务特性,转化为可落地的并发控制方案,一步步构建健壮的数据库事务体系!

相关推荐
Boilermaker19922 小时前
[MySQL] 初识 MySQL 与 SQL 基础
数据库·mysql
今晚务必早点睡2 小时前
Redis——快速入门第二课:Redis 常用命令 + 能解决实际问题
数据库·redis·bootstrap
happyhappy没有句号2 小时前
嵌入式单片机一套通关学习笔记
笔记·单片机·嵌入式硬件·学习
悠哉悠哉愿意3 小时前
【嵌入式学习笔记】工程模板建立
笔记·嵌入式硬件·学习
Hello.Reader3 小时前
Flink SQL Materialized Table 语句CREATE / ALTER / DROP介绍
数据库·sql·flink
d111111111d3 小时前
STM32外设基地址与寄存器偏移地址的深度解析
笔记·stm32·单片机·嵌入式硬件·学习
Boilermaker19923 小时前
[MySQL] 服务器架构
数据库·mysql·架构
好奇龙猫3 小时前
【AI学习-comfyUI学习-第十九节-comtrolnet艺术线处理器工作流-各个部分学习】
人工智能·学习
云老大TG:@yunlaoda3603 小时前
如何通过华为云国际站代理商CSBS进行备份策略设置?
运维·数据库·华为云