当前位置: 首页 > 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.cnnetsun.cn/news/3278746.html

相关文章:

  • C++实现一维数组主波峰检测算法:从信号处理到工程实践
  • 点对点接口开发6大核心痛点与集成平台式解决方案
  • 3种 PWM 生成方案对比:MCU 硬件定时器 vs 软件模拟 vs 专用 IC
  • LabVIEW 2023 卷积码性能对比:(2,1,5) vs (2,1,7) 在AWGN信道下的3组误码率实测
  • 全球首款80FPS大双屏墨水屏手机 于7月10日开启;Kickstarter 众筹:Big
  • 计算机大数据毕设实战-基于 Python 的抖音时尚女装用户评论舆情系统的设计与实现 基于 Python 的女装抖音评论热度态势分析系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • Java volatile 关键字深度解析:从存储金字塔到L3 Cache的3层缓存一致性
  • 93号文数据安全要求怎么落地?金融机构最难啃的骨头,有解了
  • 红外与热成像图像融合实战:基于 OpenCV 4.8 的 3 种配准算法对比
  • MBTiles vs 文件夹切片:QGIS 3.24.1 两种格式 5 项性能与部署对比
  • 昆仑万维AI大模型技术实践:从多模态生成到企业级部署优化
  • 中央SoC完整原理与车载落地详解
  • Cesium 雷达扫描 3 种方案对比:Entity Wall vs Primitive vs PostProcessStage 性能实测
  • Waterfox:比Firefox更快更隐私?这款开源浏览器,老电脑也能飞起来!
  • 干了多年物流,竟然不知道物流成本还能这么分析!
  • TPA3138D2音频放大器与STM32L041C6的音频系统设计
  • Ubuntu 22.04源码编译CARLA 0.10.0与UE5.0.3深度实践指南
  • 2026年微信小程序制作全流程:从需求整理到审核发布
  • Windows Everything 搜索失效怎么办?90% 问题一步搞定
  • Unity UGUI聊天气泡实现:自适应布局与性能优化全解析
  • 无源/有源的RC滤波电路以及有源器件介绍
  • 不只是识别细胞:超多重蛋白成像技术如何把TNBC单细胞分型带到蛋白状态观察?
  • MCP3551高精度ADC与PIC18F26J53的SPI接口应用指南
  • 技术博主的自救指南:我用百度文库 AI 生成毕业答辩 PPT 的全流程实测
  • 从功能迭代看 AI 数字人交互源码对私有化项目的长期价值
  • RS-232/RS-485/RS-422 接口选型指南:5个工业场景下的电气特性与布线要点
  • 广东伸缩门生产厂家
  • STM32F469II与EasyPull Click板信号状态管理实战
  • SAP PS 网络成本重估:KSS1/KSS2/KSII/CJN1 5步操作解决作业价格差异
  • STM32F446ZE GPIO上下拉配置与DTH-08模块应用指南