1. 首页
  2. 编程面试题
  3. Java
  4. 分布式

分布式事务的常见的解决方案有哪些?



**方案一:2PC**

两阶段提交又称2PC,2PC是一个非常经典的强一致、中心化的原子提交协议 。

中心化是指协议中有两类节点:一个是中心化协调者节点 (coordinator)和 N个参与者节点 (partcipant)。

两个阶段 :

1、第一阶段:投票阶段

2、第二阶段:提交/执行阶段。

举例订单服务A,需要调用支付服务B 去支付,支付成功则处理订单状态为待发货状态,否则就需要将购物订单处理为失败状态。 那么看2PC阶段是如何处理的。

- 阶段一执行流程:

1、事务询问协调者向所有的参与者发送事务预处理请求,称之为Prepare,并开始等待各参与者的响应。

2、执行本地事务各个参与者节点执行本地事务操作,但在执行完成后并不会真正提交数据库本地事务,而是先向协调者报告说:“我这边可以处理了/我这边不能处理”。

3、各参与者向协调者反馈事务询问的响应如果参与者成功执行了事务操作,那么就反馈给协调者Yes响应,表示事务可以执行,如果没有参与者成功执行事务,那么就反馈给协调者 No 响应,表示事务不可以执行。

- 阶段二执行流程:

1、所有的参与者反馈给协调者的信息都是Yes,那么就会执行事务提交协调者向所有参与者节点发出Commit请求

2、事务提交参与者收到Commit请求之后,就会正式执行本地事务Commit操作,并在完成提交之后释放整个事务执行期间占用的事务资源。

**方案二:3PC**

三阶段提交又称3PC,其在两阶段提交的基础上增加了CanCommit阶段,并引入了超时机制。一旦事务参与者迟迟没有收到协调者的Commit请求,就会自动进行本地commit,这样相对有效地解决了协调者单点故障的问题。

- 阶段一执行流程:

1、事务询问协调者向所有的参与者发送事务can commit请求,类似于2PC中的第二个阶段中的Prepare阶段,是一种事务询问操作,事务的协调者向所有参与者询问“你们是否可以完成本次事务?”,并开始等待各参与者的响应。

2、如果参与者节点认为自身可以完成事务就返回“YES”,否则“NO”。

- 阶段二的执行流程:

1、在阶段一中,如果所有的参与者都返回Yes的话,那么就会进入PreCommit阶段进行事务预提交。此时分布式事务协调者会向所有的参与者节点发送PreCommit请求。

2、参与者收到后开始执行事务操作,参与者执行完事务操作后(此时属于未提交事务的状态),就会向协调者反馈“Ack”表示我已经准备好提交了,并等待协调者的下一步指令。

3、如果阶段一中有任何一个参与者节点返回的结果是No响应,或者协调者在等待参与者节点反馈的过程中超时。整个分布式事务就会中断,协调者就会向所有的参与者发送“abort”请求。

- 阶段三执行流程:

1、在阶段二中如果所有的参与者节点都可以进行PreCommit提交,那么协调者就会从“预提交状态”-》“提交状态”。然后向所有的参与者节点发送"doCommit"请求。

2、参与者节点在收到提交请求后就会各自执行事务提交操作,并向协调者节点反馈“Ack”消息,协调者收到所有参与者的Ack消息后完成事务。

3、相反,如果有一个参与者节点未完成PreCommit的反馈或者反馈超时,那么协调者都会向所有的参与者节点发送abort请求,从而中断事务。

**方案三:TCC**

TCC(Try-Confirm-Cancel)又称补偿事务。其核心思想是:"针对每个操作都要注册一个与其对应的确认和补偿(撤销操作)"。

它分为三个操作:

1、Try阶段:主要是对业务系统做检测及资源预留。

2、Confirm阶段:确认执行业务操作。

3、Cancel阶段:取消执行业务操作。

TCC事务的处理流程与2PC两阶段提交类似,不过2PC通常都是在跨库的DB层面,而TCC本质上就是一个应用层面的2PC,需要通过业务逻辑来实现。这种分布式事务的实现方式的优势

在于,可以让应用自己定义数据库操作的粒度,使得降低锁冲突、提高吞吐量成为可能。 不足之处则在于对应用的侵入性非常强,业务逻辑的每个分支都需要实现try、confirm、cancel三个操作。此外,其实现难度也比较大,需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略。为了满足一致性的要求,confirm和cancel接口还必须实现幂等。

**方案四:MQ分布式事务**

上面的三种分布式事务的解决方案适用于对数据一致性要求很高的场景。如果数据强一致性要求没那么高,可以采用消息中间件(MQ)实现事务最终一致。 在支付系统中,常常使用的分布式事务解决方案就是基于MQ实现的,它对数据强一致性要求没那么高,但要求数据最终一致即可。

例如:向借呗申请借钱,借呗审核通过后支付宝的余额才会增加,但借呗和支付宝有可能不是同一个系统,这时候如何实现事务呢?实现方案如下图:

1、找花呗借钱

2、花呗借钱审核通过,同步生成借款单

3、借款单生成后,向MQ发送消息,通知支付宝转账

4、支付宝读取MQ消息,并增加账户余额

上图最复杂的其实是如何保障2、3在同一个事务中执行(本地事务和MQ消息发送在同一个事务执行),借款结束后,借呗数据处理就完成了,接下来支付宝才能读到消息,然后执行余额

增加,这才完成整个操作。如果中途操作发生异常,例如支付宝余额增加发生问题怎么办?此时需要人工解决,没有特别好的办法,但这种事故概率极低。

发布者:admin,如若转载,请注明出处:https://ai1024.vip/26590.html

QR code
//