简介

ACID,是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性:原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)。

在数据库系统中,一个事务是指:由一系列数据库操作组成的一个完整的逻辑过程。例如银行转帐,从原账户扣除金额,以及向目标账户添加金额,这两个数据库操作的总和,构成一个完整的逻辑过程,不可拆分。这个过程被称为一个事务,具有ACID特性。ACID的概念在ISO/IEC 10026-1:1992文件的第四段内有所说明。

四大特性

  • 原子性(Atomicity):一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简。

  • 一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。

  • 事务隔离(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。

  • 持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

两阶段提交

对于分布式事务一致性的研究成果包括著名的两阶段提交算法(Two-phase Commit,2PC)和三阶段提交算法(Three-phase Commit,3PC)。

两阶段提交算法最早由 Jim Gray 于 1979 年在论文《Notes on Database Operating Systems》中提出。其基本思想十分简单,既然在分布式场景下,直接提交事务可能出现各种故障和冲突,那么可将其分解为预提交和正式提交两个阶段,规避冲突的风险。

  • 预提交:协调者(Coordinator)发起提交某个事务的申请,各参与执行者(Participant)需要尝试进行提交并反馈是否能完成;
  • 正式提交:协调者如果得到所有执行者的成功答复,则发出正式提交请求。如果成功完成,则算法执行成功。

在此过程中任何步骤出现问题(例如预提交阶段有执行者回复预计无法完成提交),则需要回退。 两阶段提交算法因为其简单容易实现的优点,在关系型数据库等系统中被广泛应用。当然,其缺点也很明显。整个过程需要同步阻塞导致性能一般较差;同时存在单点问题,较坏情况下可能一直无法完成提交;另外可能产生数据不一致的情况(例如协调者和执行者在第二个阶段出现故障)。

三阶段提交

三阶段提交针对两阶段提交算法第一阶段中可能阻塞部分执行者的情况进行了优化。具体来说,将预提交阶段进一步拆成两个步骤:尝试预提交和预提交。

完整过程如下:

  • 尝试预提交:协调者询问执行者是否能进行某个事务的提交。执行者需要返回答复,但无需执行提交。这就避免出现部分执行者被无效阻塞住的情况;
  • 预提交:协调者检查收集到的答复,如果全部为真,则发起提交事务请求。各参与执行者(Participant)需要尝试进行提交并反馈是否能完成;
  • 正式提交:协调者如果得到所有执行者的成功答复,则发出正式提交请求。如果成功完成,则算法执行成功。

其实,无论两阶段还是三阶段提交,都只是一定程度上缓解了提交冲突的问题,并无法一定保证系统的一致性。首个有效的算法是后来提出的 Paxos 算法