分布式事务指涉及操作多个数据库的事务,在分布式系统中,各个节点之间在物理上相互独立,通过网络进行沟通和协调。
二阶段提交(Two-Phase Commit)指在计算机网络及数据库领域内,为了使分布式数据库的所有节点在进行事务提交时都保持一致性而设计的一种算法。在分布式系统中,每个节点虽然都可以知道自己的操作是否成功,却无法知道其他节点的操作是否成功。
在一个事务跨越多个节点时,为了保持事务的ACID特性,需要引入一个作为协调者的组件来统一掌控所有节点(称作参与者)的操作结果,并最终指示这些节点是否真正提交操作结果(比如将更新后的数据写入磁盘等)。因此,二阶段提交的算法思路可以概括为:参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈决定各参与者是提交操作还是中止操作。
Prepare(准备阶段)
事务协调者(事务管理器)给每个参与者(源管理器)都发送Prepare消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务,写本地的redo和undo日志但不提交,是一种“万事俱备,只欠东风”的状态。
Commit(提交阶段)
如果协调者接收到了参与者的失败消息或者超时,则直接给每个参与者都发送回滚消息,否则发送提交消息,参与者根据协调者的指令执行提交或者回滚操作,释放在所有事务处理过程中使用的锁资源,如下图所示。
两阶段提交的缺点
两阶段提交的缺点如下:
- 同步阻塞问题:在执行过程中,所有参与者的任务都是阻塞执行的。
- 单点故障:所有请求都需要经过协调者,在协调者发生故障时,所有参与者都会被阻塞。
- 数据不一致:在二阶段提交的第2 阶段,在协调者向参与者发送Commit(提交)请求后发生了局部网络异常,或者在发送Commit请求过程中协调者发生了故障,导致只有一部分参与者接收到Commit请求,于是整个分布式系统出现了数据不一致的现象,这也被称为脑裂。
- 协调者宕机后事务状态丢失:协调者在发出Commit消息之后宕机,唯一接收到这条消息的参与者也宕机,即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没有人知道事务是否已被提交。