分布式事务的实现,一般有三种方案:

  1. 基于 XA 协议的二阶段提交协议方法;
  2. 三阶段提交协议方法;
  3. 基于消息的最终一致性方法

基于 XA 协议的二阶段提交方法

XA是一个分布式事务协议,规定了事务管理器和资源管理器接口,可以分为两部分:事务管理器本地资源管理器

大致原理是:事务管理器作为协调者,负责各个本地资源的提交和回滚,而资源管理器就是分布式事务的参与者,通常由数据库实现。

基于 XA 协议的二阶段提交方法中,二阶段提交协议(The two-phase commit protocol,2PC),用于保证分布式系统中事务提交时的数据一致性,是 XA 在全局事务中用于协调多个资源的机制。

两阶段提交

投票为第一阶段,协调者会向事务的参与者发起执行操作的请求,允许他们发起提交,参与者收到请求后,会执行请求中的事务,记录日志信息但不提交,待参与者执行成功后,向协调者发送yes表示同意操作,若不成功,则发送no,表示终止。

当所有的参与者都返回了yes或者no信息后,才会进入提交阶段。

在该阶段,如果所有的参与者都发送的是yes,那么协调者将通知所有参与者提交事务,参与者收到通知后,才会完成剩下的操作。如果有一个参与者提交了no,那么所有的参与者都无法提交该事务。

不足:

  1. 同步阻塞问题:该算法执行过程中,所有参与者未收到协调者信息的情况下,都处于事务阻塞状态,如果占用临界资源,则其他系统也无法。
  2. 单点故障问题:如果资源管理器发生了故障,那么整个系统就会处于停滞状态。
  3. 数据不一致问题:在提交阶段,如果协调者给参与者发送确认提交的信息时网络异常,会导致一部分参与者无法提交事务,而导致数据不一致。

三阶段提交

三阶段提交是对二阶段提交的改进,为了防止数据不一致以及同步阻塞问题,引入了超时机制和准备阶段。如果参与者或者协调者在规定的时间内没有收到信息,则选择提交或者终止整个事务。

在第一阶段和第二阶段中间引入了一个准备阶段,也就是在提交阶段之前,加入了一个预 提交阶段。在预提交阶段排除一些不一致的情况,保证在最后提交之前各参与节点的状态是一致的。

也就是说变为了三个阶段:可以提交,预提交,和提交。

可以提交和之前的一样,不过多阐述。

预提交是协调者根据参与者的状态来决定是否可以预提交,如果所有参与者都回复yes,协调者就会执行事务的预执行:

首先是发送预提交请求,然后参与者收到后,执行事务操作,并记录Undo和Redo信息记录到事务日志,之后,参与者如果执行成功,则返回ACK响应,同时开始等待最终指令。

到了正式提交,才是真正的提交具体的事务。

不管是二阶段还是三阶段提交,都无法解决性能低,包括数据出现不一致的情况。

基于分布式消息的最终一致性方案

这个就是引入了一个中间件,比如消息队列,用于存储消息,比如日志或者消息可以存进来,异步的去进行执行,来达到数据最终的一致性,中间还是会有部分时间的不一致。

参考

《分布式技术原理与算法解析》