当前位置: 首页 > news >正文

什么是数据库事务?一文搞懂 ACID 四大特性(一)

数据库事务系列 · 第 1 篇

引言:一次转账引发的数据危机

想象你正在开发银行转账系统的核心模块。用户张三发起一笔1000元的转账给李四,程序逻辑清晰地分为两步:

  1. 张三账户余额减少1000元。
  2. 李四账户余额增加1000元。

一切看似完美。然而,就在程序成功执行完第一步、正准备执行第二步时,数据库服务器突然宕机了。

系统重启后,你惊恐地发现:张三的账户确实少了1000元,但李四的账户余额却纹丝不动

那这1000元凭空消失了。更可怕的是,没有任何错误日志能告诉你发生了什么。这就是没有事务机制的数据库世界——每个操作都是孤立的个体,一次意外就可能导致数据永久性地陷入不一致状态。

为了解决这类问题,数据库引入了**事务(Transaction)**这一核心概念。

一、事务的概念:一组操作的“生死契约”

事务,是一组数据库操作的集合,它是数据库执行的最小逻辑单元。

这个单元有一个不可动摇的铁律:这组操作要么全部成功(提交,COMMIT),要么全部失败(回滚,ROLLBACK)。绝不允许“成功一半”的中间状态存在。

案例聚焦:回到转账案例,在事务的保护下,它变成了一个不可分割的整体。

-- 这是一个完整的事务-- 操作1:张三账户减1000UPDATEaccountSETbalance=balance-1000WHEREname='张三';-- 操作2:李四账户加1000UPDATEaccountSETbalance=balance+1000WHEREname='李四';-- 如果上述两步都成功,则执行 COMMIT(提交),数据永久生效。-- 如果任何一步失败,则执行 ROLLBACK(回滚),两步操作全部撤销。
  • 正常世界:两条UPDATE都成功,数据库执行COMMIT。数据更新,皆大欢喜。
  • 异常世界:步骤1成功,步骤2失败(如网络超时、账户异常)。事务机制会立即执行ROLLBACK,将张三的余额恢复到修改前的状态。最终结果是:张三钱没少,李四钱没多,数据依然保持一致

事务的本质:它为应用程序提供了一种简化的编程模型。程序员只需告诉数据库“要么全做,要么全不做”,而无需在代码中处理复杂的并发、网络、硬件等底层异常。事务是应用层与复杂数据层之间的可靠“契约”。

二、事务的四大特性(ACID):四大护法,缺一不可

正是ACID这四个特性,共同构成了事务的完整承诺。我们用转账案例,逐一剖析每个特性的角色。

1. 原子性(Atomicity)——“全做或全不做”
  • 案例聚焦:原子性保证了张三扣钱和李四加钱必须作为一个整体执行。如果李四加钱失败,整个事务会回滚,张三的扣钱操作也会被撤销。你永远不会看到“钱扣了但没到账”这种中间状态。
  • 技术基石:原子性由Undo Log(回滚日志)保障。每次修改数据前,数据库都会在Undo Log中记录修改前的旧值。一旦需要回滚,数据库就利用这些旧值将数据恢复原状,仿佛操作从未发生。
2. 一致性(Consistency)——“合法才是王道”
  • 案例聚焦:一致性要求,事务执行前后,张三和李四的账户总金额必须保持不变(1000+2000 = 1100+1900)。同时,如果表上有“余额不能为负”的约束,一致性也保证不会出现负余额。
  • 关键说明:一致性需要应用层和数据库共同保证。数据库能确保其自身约束(如主键、外键)不被破坏。但像“转账总额不变”这样的业务规则一致性,必须由你的代码(正确地执行两条UPDATE)来保证。如果代码只扣了张三的钱而忘了给李四加钱,数据库的约束依然满足,但业务上已经不一致了。
3. 隔离性(Isolation)——“让并发事务和平共处”
  • 案例聚焦:当张三给李四转账的同时,王五也在给李四转账。隔离性确保了这两个并发的事务不会互相干扰。一个事务不会读取到另一个事务尚未提交的中间状态(比如“李四账户加了1000”但事务还未提交)。
  • 技术基石:隔离性主要通过锁机制MVCC(多版本并发控制)实现。数据库提供了四种隔离级别,在数据一致性和并发性能之间做权衡。我们将在本系列第2、3篇中深入剖析,届时你会看到“脏读”、“不可重复读”等现象是如何产生和解决的。
4. 持久性(Durability)——“一旦提交,永不遗忘”
  • 案例聚焦:当客户端收到“转账成功”的提示后,哪怕数据库所在机房突然断电,重启后,张三扣1000、李四加1000的最终结果依然必须存在。数据不能因为系统故障而回退。
  • 技术基石:持久性由Redo Log(重做日志)保障。数据修改时,会先以顺序写的方式快速写入Redo Log,并立即返回“提交成功”。之后,数据库后台才会慢慢将数据刷新到磁盘。即使刷盘前系统崩溃,重启后也能根据Redo Log重做已提交的事务,确保数据不丢失。

核心总结:Undo Log 保证了“可以撤回来”,Redo Log 保证了“提交了不丢”。原子性、隔离性、持久性(A、I、D)三者,最终共同服务于一致性(C)这个终极目标,确保数据库从一个正确状态转移到另一个正确状态。

三、事务的版本支持:选对引擎是前提

理解了ACID的理论,我们进入实操前的最后一步准备:确认MySQL环境的支持情况。

在MySQL中,并不是所有存储引擎都支持事务。这直接决定了你能否使用BEGINCOMMITROLLBACK等命令。

  • InnoDB(默认引擎)完整支持事务。所有ACID特性及相关的并发控制机制都在InnoDB中实现。使用事务,必须确保表使用InnoDB引擎
  • MyISAM(早期引擎)不支持事务。在其上执行事务命令不会报错,但不会有任何回滚或提交的效果。

你可以通过以下命令查看MySQL支持的引擎及事务支持情况:

SHOWENGINES;

重点关注Engine(引擎名)和Transactions(是否支持事务)两列。只有标记为YES的引擎才能使用事务。

因此,创建表时务必指定或确认默认引擎为InnoDB

CREATETABLEaccount(idINTPRIMARYKEY,nameVARCHAR(20),balanceDECIMAL(10,2))ENGINE=InnoDB;-- 明确指定引擎
四、事务的提交方式与实操演示

现在我们具备了所有理论基础和环境前提,开始动手验证。

1. 提交方式

MySQL默认采用自动提交(AUTOCOMMIT=1)。这意味着每条DML语句执行后,都会自动被提交为一个独立的事务。

查看当前提交方式

SHOWVARIABLESLIKE'autocommit';

设置提交方式(在演示中,我们通常通过显式BEGIN来开启事务,它会临时影响提交行为):

-- 关闭自动提交,改为手动SETautocommit=0;-- 或直接使用 BEGIN/START TRANSACTION 显式开启事务
2. 核心事务命令速查
命令作用
BEGIN;/START TRANSACTION;开启一个事务。
SAVEPOINT 名称;在事务内创建保存点(存档)。
ROLLBACK TO 名称;回滚到指定保存点
ROLLBACK;回滚整个事务到开始状态。
COMMIT;提交事务,使所有更改永久生效。
3. 完整实操演示:见证原子性与持久性

为了直观展示,我们使用两个MySQL会话(终端A和终端B)。请先将两个终端的隔离级别临时设置为READ UNCOMMITTED,以便我们在事务未提交时也能看到数据变化,从而完整追踪过程。

SETSESSIONTRANSACTIONISOLATIONLEVELREADUNCOMMITTED;

第一阶段:开启事务与分段操作

  1. 终端A开启事务:BEGIN;


  1. 终端A插入数据:INSERT INTO account VALUES (1, '张三', 100);

  2. 终端B查询:SELECT * FROM account;→ 可以看到“张三”记录。

  1. 终端A创建保存点:SAVEPOINT s1;
  2. 终端A插入数据:INSERT INTO account VALUES (2, '李四', 10000);
  3. 终端B查询:SELECT * FROM account;→ 可以看到两条记录。

第二阶段:部分回滚(展现原子性的控制力)

  1. 终端A回滚到保存点:ROLLBACK TO s1;
  2. 终端B查询:SELECT * FROM account;结果只显示“张三”,“李四”记录消失。
    • 结论:事务可以精确回滚到任意保存点,证明了原子性的“全做或全不做”的控制能力。

第三阶段:完整回滚 vs 最终提交(对比原子性的终结与持久性的开始)

  1. 终端A回滚整个事务:ROLLBACK;
  2. 终端B查询:SELECT * FROM account;→ 表只剩张三。

(现在,重新开启事务,对比提交的效果)

  1. 终端A重新开启事务:BEGIN;
  2. 终端A插入数据:INSERT INTO account VALUES (1, '张三', 100);
  3. 终端A直接提交:COMMIT;
  4. 终端B查询:SELECT * FROM account;→ “张三”记录永久存在。

第四阶段:模拟崩溃(验证持久性)

  1. 模拟崩溃:强制关闭终端A的连接。
  2. 终端B再次查询:SELECT * FROM account;
    • 最终结果:“张三”记录完好无损。
    • 结论:一旦COMMIT,修改就永久生效,即使客户端崩溃也无法影响,证明了持久性。
五、总结

本文作为MySQL事务系列的第一篇,我们完成了以下学习:

  1. 事务的概念:一组不可分割的操作集合,要么全成功(COMMIT),要么全失败(ROLLBACK)。
  2. ACID四大特性
    • 原子性(A):由Undo Log保障。
    • 一致性(C):最终目标,需应用层逻辑保证。
    • 隔离性(I):由锁和MVCC保障。
    • 持久性(D):由Redo Log保障。
  3. 使用前提:表引擎必须是InnoDB
  4. 核心操作:通过实操演示了BEGINCOMMITROLLBACKSAVEPOINT命令,并验证了原子性和持久性。

📌 下篇预告

事务的隔离性是ACID中最精妙也最复杂的部分。多个事务并发执行时,会产生哪些问题?脏读、不可重复读、幻读具体指什么?四种隔离级别又是如何应对它们的?

下一篇,我们将用大量实操演示,深入剖析这些并发问题的本质。敬请期待
*:通过实操演示了BEGINCOMMITROLLBACKSAVEPOINT命令,并验证了原子性和持久性。

http://www.jsqmd.com/news/1165379/

相关文章:

  • Claude Code 实战:把边界和取舍讲清楚
  • Apache DolphinScheduler 6 月治理优化,补齐调度运维全链路细节
  • AI初创企业如何评估与使用免费算力资源,避免技术锁定风险
  • 2026年7月最新沈阳雅典官方售后客服中心地址电话及服务网点分布 - 亨得利官方服务中心
  • Python五子棋人机对战:从零实现AI博弈算法与Pygame图形界面
  • JDK 8u491 3种Linux安装方案对比:Oracle RPM vs OpenJDK vs 源码包
  • 设计系统 Figma 到代码的自动化同步:Token 桥梁设计
  • 腾讯混元Hy3模型:MoE架构下的高性价比物理模拟与推理应用
  • HackRF-One 1MHz-6GHz 性能解析:8-bit 采样与 15 dBm 发射功率实测指南
  • 基于TB6593FNG和PIC18F96J65的直流电机控制系统设计
  • 【单片机毕业设计】基于 51/STM32 单片机的智能温控风扇调速报警系统设计与实现,基于 51/STM32 单片机的多档位 PWM 温控散热控制系统开发(025501)
  • 【P8218 求区间和】一维前缀和入门完整题解博客
  • 深圳积家回收价格查询和各大回收平台实测排行(2026年7月最新数据) - 积家官方售后服务中心
  • STM32 SPI 模式配置实战:W25Q64 Flash 读写时序与 CPOL/CPHA 寄存器详解
  • 反函数求解3大易错点解析:从分段函数到复合函数定义域判定
  • TMC7300与PIC18F86J16构建高效有刷直流电机控制系统
  • C++集成YOLOv11-CLS图像分类模型:基于ONNX Runtime的部署实战
  • 面向海量视频数据的智能存储优化技术研究:AI驱动的视频空间压缩方法与应用探索
  • Python OpenCV 图像处理:阈值分割详解与实战
  • 硬件工程师工具网站2024精选:9大场景30+站点实测与效率对比
  • 梳理一下做一个前端项目需要的点
  • DS18B20 多点测温系统设计:单总线挂载 3 个传感器与地址寻址实战
  • Cesium 雷达扫描 3 种方案对比:Entity Wall vs Primitive vs PostProcessStage 性能实测
  • 2026桃心云手机深度实测 内置AI安卓云机全功能测评
  • Unity游戏实时NPC语音生成:基于IndexTTS的本地化集成方案
  • 适合孵化 OPC 项目的 AI 编码工具:2026 年选型指南与实践评测
  • 行业内专业的工业电源厂商
  • 2026年7月最新哈尔滨浪琴官方售后服务热线与网点地址查询 - 浪琴官方售后服务中心
  • 面向俄 CRPT 监管的诚实标签全链路采集关联系统技术方案 —— 兴通一体化软硬件实现赋码采集与合规文件输出
  • 计算机毕业设计之基于springboot艺术品拍卖网站的设计与实现