数据库事务是数据库管理系统中执行的一个逻辑工作单元,由一个有序的数据库操作序列构成。这个概念由计算机科学家吉姆格雷在二十世纪七十年代系统提出,他后来因此获得图灵奖。事务将一组数据库操作封装为不可分割的整体,要么全部成功并对数据库产生永久影响,要么全部不执行,不存在只执行部分操作的中间状态。事务解决了一个根本矛盾,在共享并发的数据库环境中如何确保数据的正确性。
从事务的严格定义来看,它是一个程序执行单元,访问并可能修改数据库中的数据项。事务边界由应用程序显式声明,以COMMIT表示所有操作成功并要求持久化,以ROLLBACK表示因异常需要撤销已执行的操作。当前许多数据库默认开启了自动提交模式,每条单语句作为一个隐式事务自动提交,但这只是简化编程的工程手段而非事务概念的完整表达。多语句构成的显式事务才是事务本质所在。
事务的必要性可以通过银行转账场景来直观理解。从账户甲转一千元到账户乙,需要两个更新语句依次执行。如果第一步扣款完成而第二步增值尚未执行时服务器断电了,转账中断导致总金额凭空减少。事务机制将扣款和增值置于同一事务保护下,原子性保证两个操作要么都完成要么都回滚,隔离性保证并发转账不会互相串数据,持久性保证提交后账目不会丢失。
事务还内含着对并发访问的约束。多个用户同时读写同一数据库时如果没有并发保护,脏读、不可重复读和幻读等异常就会传播。事务通过锁机制和多版本并发控制技术,为每个活跃事务营造相互隔离的执行环境,让每个事务仿佛独占整个数据库。事务理论直指关系型数据库核心架构,是所有数据库从业者必须掌握的基础知识。
当前主流数据库系统无论是Oracle、SQL Server、DB2,还是开源的MySQL、PostgreSQL,以及分布式新架构的TiDB、OceanBase,都持续投入事务处理机制的研发。不同系统在隔离级别的默认值和具体并发行为上存在细微差异,这些差异本身也是软考命题的重要来源。事务思想还深刻影响了分布式系统的设计范式,延伸出了两阶段提交协议以及对Paxos和Raft共识算法的工程应用。
ACID是事务模式的四个基本特性,分别对应原子性、一致性、隔离性和持久性。这四个特性构成事务正确执行的充要条件,任何一个的缺失都会导致事务概念失效。在软考各相关科目中,ACID的出题频率极高,命题人偏爱用迷惑性场景考察考生是否真正吃透了底层含义。
原子性是事务最直观的特性,要求事务包含的所有操作要么全部完成要么仿佛从未发生。原子二字借鉴物理学中对不可再分粒子的隐喻,说明事务所囊括的操作序列是一个紧密不可切割的最小执行单位。从底层机制看,原子性依赖精密的事务日志子系统和恢复管理器,核心技术是回滚日志。
当事务执行并逐渐修改数据页时,数据库不会立刻将新数据覆盖到磁盘。大多数数据库将修改先写入内存缓冲池形成脏页,同时将每次修改的前像即原始旧值记录到回滚日志中。回滚日志的写入遵循先写日志原则,即在任何物理修改落到持久化存储之前,描述修改的日志记录必须先完整写入磁盘日志文件,此顺序绝对不可颠倒。一旦系统在修改过程中崩溃,而日志已入磁盘,重启后恢复管理器便读取前像信息逐条撤销脏数据。
当出现任何异常时,原子性的保护逻辑就自动激活。异常范围远超SQL报错,还包括显式ROLLBACK、断电、内存耗尽、磁盘写满、约束违反、触发器异常、网络链路中断等。检测到异常后数据库即启动回滚程序,读取与该事务关联的所有前像记录逐条恢复数据页。回滚完整执行后事务的所有痕迹才从数据库中彻底抹除。这套回滚机制是数据库最基础的容错能力。
除了回滚日志,原子性的工程实现还依赖检查点机制。随着数据库运行,回滚日志会无休止增长。检查点强制将内存中已提交事务的脏页刷入磁盘并在日志流中标记检查点记录,之后在此之前的所有回滚日志条目便可安全回收。崩溃重启时也无需从头扫描日志,只需从最近检查点开始向后分析,决定哪些已提交修改需重做、哪些未提交修改需回滚,极大缩短恢复时间。
一致性是ACID中理解门槛最高的特性。许多教材描述为事务使数据库从一个一致状态迁移到另一个一致状态,若失败则回退到原状态。这个定义虽正确,但容易让学习者误以为一致性全由数据库系统自动保底。真相是数据库只能保证其所维护的那部分一致性约束不被破坏,而什么状态算业务语义上的一致必须由应用程序设计者显式定义。
数据库层面可确保的一致性指数据满足所有已声明的完整性约束。实体完整性要求每个表必须定义主键且主键值不能为空不能重复。参照完整性要求外键取值要么为空要么精准对应被参照表的主键值,不允许出现悬挂引用。用户自定义完整性约束包括CHECK约束、NOT NULL约束、UNIQUE约束以及触发器中实现的自定义校验逻辑。事务通过原子性和隔离性的组合保障了这些约束的运行环境。
业务层面的一致性则需要应用设计者自行保障。银行转账的总金额守恒、库存数量不能为负、订单金额与支付金额必须匹配等都是语义级规则。假如一个事务扣款两千却增值三千,只要未违反约束,数据库就会欣然提交,从内部一致性视角看一切正常但这笔转账在业务上错了。这就是一致性在ACID中是唯一需要数据库和应用共同承担责任的特性。
在软考命题中一致性常被用作干扰选项。命题人喜欢制造一致性是事务天然产物的陷阱来测试考生的辨析能力。正确的理解是事务的原子性和隔离性为数据合规提供底层支撑但它们只是一致性的必要条件而非充分条件。没有正确的业务逻辑和约束设计,光靠事务特性无法确保全局一致性。这一认知落差点在模拟题和真题中被反复利用。
隔离性是ACID中技术内涵最深厚、命题密度最高的一块。其基本语义是多个事务并发执行时互不感知,每个事务的视角下整个数据库仿佛只有自己在运行。理想状态下完全隔离的并发结果应与这些事务串行执行的结果一致,称为可串行化。但完全隔离意味着吞吐量断崖式下跌,数据库设计者必须在准确性和性能间寻找平衡,于是定义了四个渐进的隔离级别供应用按需选择。
SQL标准规定的四个级别从低到高分别是读未提交、读已提交、可重复读和可串行化。读未提交保护最薄弱,一个事务可读到另一个未提交事务正在修改的临时数据,由此产生脏读,即读到了一条事后被回滚掉的幽灵数据。读未提交几乎没有并发安全防护,生产环境极少启用。
读已提交是Oracle和PostgreSQL的默认级别,事务只能看到其他事务已完成提交的修改,杜绝了脏读。但它无力防御不可重复读,即一个事务内两次读取同一条记录之间另一个事务修改并提交了该记录导致第一次读到旧值第二次读到新值。可重复读是MySQL InnoDB的默认级别,保证事务内对已存在记录的每次读取都返回一致的值,解决了不可重复读但挡不住幻读。
幻读指一个事务按条件查询出结果集后,另一个并发事务插入了一条满足该条件的新记录并提交,原事务再次查询时多了一条不存在过的数据行。可串行化通过强制串行执行或间隙锁等手段将脏读、不可重复读和幻读一网打尽。四个级别的名称、排序、允许的异常类型及典型使用场景均是高频考点,考生必须看到一个异常现象描述就能识别其类型并反推出最低应达到的隔离级别。
持久性赋予事务一种终极承诺,一旦数据库回复了提交成功的确认,事务所做的全部修改就已牢不可破地固化在持久存储中,即便紧随其后遭遇宕机断电或内核崩溃也不会丢失。持久性是ACID的承重墙,若提交后数据还可能丢失则其他三个特性全部失去意义。实现持久性的核心技术是重做日志。
事务发出COMMIT后数据库首先不是将脏页刷入数据文件,而是将事务产生的所有修改编码为重做日志记录持续写入磁盘上的日志文件并调用强制刷盘操作确保穿透操作系统页缓存到达物理存储,之后才向客户端返回成功。这个过程同样遵循先
本篇完!