分布式事务模式

分布式事务分为:两阶段提交(2PC)、三阶段提交Three-phase commit(3PC)、补偿事务(TCC)、本地消息表。

两阶段提交(2PC)

两阶段提交(2PC)是种标准化协议,将提交操作分为两个独立单元。

此模式需要一个协调器,协调处理分布式服务应用的活动和同步。

实现

阶段1:

需要提交数据的服务,先将数据记录写入Undo Log,返回操作“成功/失败”消息。

阶段2:

所有事务参与者回复“成功”消息后,协调器向每个服务发出“提交”指令,事务参与者执行提交,并返回"成功/失败”消息,协调者收到所有参与者"完成"消息后,结束事务。

一阶段中任何参与者返回"终止"消息,或协调者发现询问超时,协调者会向所有参与者发出"回滚"请求。

缺点

二阶段提交执行过程中,参与者处于阻塞状态,任何节点超时都将导致其他节点执行“回滚”,策略上略显保守。

三阶段提交(3PC)

三阶段提交为2PC改进版,2PC明显缺点是协调者发出“提交”指令后,参与者出现崩溃,崩溃恢复后参与者数据会出现不一致。

3PC将2PC commit过程1分为2,分为preCommit和commit。

参与者收到协调者发送的preCommit指令后,参与者等待commit指令时,若出现超时,默认执行commit。

若事务参与者出现崩溃,需要一个定时补偿机制,参与者收到commit,或者全部参考者都收到preCommit,  则执行commit,否则执行“回滚"。

优点

单点故障后仍能实现数据一致性。

缺点

网络分区问题导致协调者在发出后preCommit后网络异常,协调者发出”撤销“操作,参与者却执行默认commit。

补偿事务(TCC)

TCC编程模式本质也是两阶段协议,不同之处TCC编程模式与具体业务耦合。

TCC编程模式实现步骤:

1、事务参与者都需要实现try、confirm、cancle接口。

2、事务发起者向协调器发出事务请求,协调器调用事务参与者try方法执行资源预留操作。

3、若参与者try方法预留操作失败,协调者向调用所有参与者cancle方法执行回滚,cancle方法需实现幂等,应对网络引发的重试。

4、若参与者try方法都返回“OK”,则向所有参与者调用confirm方法。

5、参与者confirm方法都返回“OK",协调器结束分布式事务。

6、若有参与者confirm方法返回”失败“,或发现网络分区,协调器会执行重试,若重试失败,需要事务补偿机制执行补偿。

以转账为例说明TCC操作:

try阶段

预留资源,预留执行金额冻结,账户余额保持不变,其他事务不能使用预留资源,只有冻结操作成功,才认为try阶段成功。

confirm阶级

执行扣款操作,使用冻结记录更新账户余额。

本地消息表

本地消息表对本地数据库事务负责,所涉及到的子系统,使用消息队列 进行通知。

消息发起方使用消息表,记录发送的消息及状态,消息表和本地业务数据表处于同一个事务中。

通过MQ把消息传递给子系统,消息接收方需具有幂等性。

子系统接受消息并执行处理,处理成功或失败都需要通知消息发出方以便确认、补偿或回滚等操作。

生产方和消费方需定时查看本地消息表,处理尚未完成或者失败的消息。

方案遵循BASE理论提到的最终一致性。

优点

通过最终一致性避免了分布式事务。

缺点

消息表与到业务表处于同一个事务中。