分布式事务解决方案
花开堪折直须折,莫待无花空折枝。
分布式事务是指事务的操作位于不同的节点上,需要保证事务的ACID特性。在分布式架构下,每个节点只知晓自身操作的成功与失败,无法知悉其他节点的操作状态。当一个事务跨多个节点时,为了保持事务的原子性与一致性,从而引入一个协调者来统一管控所有参与者的操作结果,并指引它们最终是否把操作结果进行诊治的提交(commit)和回滚(rollback)。例如在购物下单场景中,库存和订单如果不在同一个节点上,就涉及分布式事务。
在分布式系统中要实现分布式事务,常见的解决方案有两段提交(2PC)、三段提交(3PC)、事务补偿(TCC)、本地消息表(异步确保)、MQ事务方案(可靠消息事务)、最大努力通知和Saga事务。

二阶段提交协议(Two-phase Commit,即 2PC)是常用的分布式事务解决方案,即将事务的提交过程分为准备阶段和提交阶段两个阶段来进行处理,通过引入协调者(Coordinator)来协调参与者的行为,并最终决定这些参与者是否要真正执行事务。
准备阶段(投票阶段)
协调者询问参与者事务是否执行成功,参与者发回事务执行结果,但该阶段并未提交事务。
提交阶段(执行阶段)
如果事务在每个参与者上都执行成功,事务协调者发送通知让参与者提交事务;否则,协调者发送通知让参与者回滚事务。
在准备阶段,参与者执行了事务,但是还未提交。只有在提交阶段接收到协调者发来的通知后,才进行提交或者回滚。
commit)的请求;2PC优缺
优点
缺点
commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。
三阶段提交协议是二阶段提交协议的改进版本,其有两个改动点。
即除了引入超时机制之外,3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有CanCommit、PreCommit和DoCommit三个阶段。
3PC优缺点
优点
相比二阶段提交,三阶段提交降低了阻塞范围,在等待超时后协调者或参与者会中断事务。避免了协调者单点问题,阶段 3 中协调者出现问题时,参与者会继续提交事务。
缺点
数据不一致问题依然存在,当在参与者收到 preCommit 请求后等待 doCommit 指令时,此时如果协调者请求中断事务,而协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。

TCC(Try Confirm Cancel)方案是一种应用层面侵入业务的两阶段提交,是目前最火的一种柔性事务方案。TCC采用了补偿机制,其核心思想就是针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。它分为Try、Confirm和Cancel三个阶段。
Try 阶段主要是对业务系统做检测及资源预留;
Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的,即:只要Try成功,Confirm一定成功;
Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。
转账例子:假入 Bob 要向 Smith 转账,思路大概是: 我们有一个本地方法,里面依次调用。
TCC优缺点
优点
跟2PC比起来,实现以及流程相对简单了一些,但数据的一致性比2PC差。
缺点
在2和3步中都有可能会失败。TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。
本地消息表方案的核心思路是将分布式事务拆分成本地事务进行处理。通过在事务主动发起方额外新建事务消息表,事务发起方处理业务和记录事务消息在本地事务中完成,轮询事务消息表的数据发送事务消息,事务被动方基于消息中间件消费事务消息表中的事务。

上图中整体的处理步骤如下:
本地消息表优缺点
优点
避免了分布式事务,实现了最终一致性。
缺点
消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。
MQ事务方案是对本地消息表的封装,将本地消息表基于 MQ 内部,其他方面的协议基本与本地消息表一致。

最大努力通知方案是对MQ事务方案的进一步优化。它在事务主动方增加了消息校对的接口,如果事务被动方没有接收到消息,此时可以调用事务主动方提供的消息校对的接口主动获取。
其适用于业务通知类型,例如微信交易的结果,就是通过最大努力通知方式通知各个商户,既有回调通知,也有交易查询接口。

Saga 事务核心思想是将长事务拆分为多个本地短事务,由 Saga 事务协调器协调,如果正常结束那就正常完成,如果某个步骤失败,则根据相反顺序一次调用补偿操作。
Saga 事务基本协议如下:
Saga 的执行顺序有两种:
TCC事务补偿机制有一个预留(Try)动作,相当于先报存一个草稿,然后才提交;而Saga事务没有预留动作,直接提交。对于事务异常,Saga提供了向后恢复和向前恢复两种恢复策略。
向后恢复(backward recovery)
backward recovery,即上面提到的第二种执行顺序,其中j是发生错误的sub-transaction,这种做法的效果是撤销掉之前所有成功的sub-transation,使得整个Saga的执行结果撤销。

向前恢复(forward recovery)
forward recovery,即适用于必须要成功的场景,执行顺序是类似于这样的:T1, T2, ..., Tj(失败), Tj(重试),..., Tn,其中j是发生错误的sub-transaction。该情况下不需要Ci。

各分布式事务方案的常见使用场景:
上述几种方案都是分布式事务的理论知识,Seta是分布式解放方案的一个落地实现。
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
花开堪折直须折
莫待无花空折枝