分布式事务方案


1、二阶段提交协议(Two-Phase Commit)

1.1、运行过程

二阶段的一个解决思路就是找出一个全局的协调者,每个参与者的成功或失败都通知协调者,最终由协调者发布是否全部提交还是全部回滚

分为两个阶段:

  • 第一阶段:准备阶段(投票阶段)
  • 第二阶段:提交阶段(写入数据阶段)

第一阶段(投票阶段)

该阶段其实就是执行我们所有参与者的代码的阶段,执行完之后将结果成功或失败最终反馈给全局协调者,由全局协调者做进一步的判断,但是此时的事务是还没有提交的

第二阶段(提交阶段)

在经过第一阶段协调者的询盘之后,各个参与者会回复自己事务的执行情况,这时候存在 3 种可能性:

  1. 所有的参与者都回复能够正常执行事务。
  2. 一个或多个参与者回复事务执行失败。
  3. 协调者等待超时。

第 1 种情况,协调者将向所有的参与者发出提交事务的通知,具体步骤如下:

  1. 协调者向各个参与者发送 commit 通知,请求提交事务;
  2. 参与者收到事务提交通知之后执行 commit 操作,然后释放占有的资源;
  3. 参与者向协调者返回事务 commit 结果信息。

流程图如下所示:
在这里插入图片描述

第二种情况及第三情况 出现异常需要回滚操作:

  1. 协调者向各个参与者发送事务 rollback 通知,请求回滚事务;
  2. 参与者收到事务回滚通知之后执行 rollback 操作,然后释放占有的资源;
  3. 参与者向协调者返回事务 rollback 结果信息。

流程图如下所示:

在这里插入图片描述

1.2、存在的问题

  • 同步阻塞: 在整个流程中每个参与者的事务都没有释放,等待统一提交之后才会释放,所以会阻塞其他的请求。
  • 单点故障: 由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。
  • 数据不一致: 当参与者接收到commit请求之后,某些参与者故障,只提交了某些事务。

针对上述问题可以引入 超时机制互询机制 在很大程度上予以解决。

超时机制: 若事务久久没有回复,则直接rollback策略。

互询机制: 参与者互相询问是否接收到了通知,如A询问B是否收到了commit或rollback的通知,若收到了可以与B做相同的操作。如果B此时还没有收到通知则可以稍微等待直到超时执行rollback策略。

2、三阶段提交协议

三阶段提交(Three-phase commit),也叫三阶段提交协议(Three-phase commit protocol),是二阶段提交(2PC)的改进版本。

在这里插入图片描述

与二阶段不同有两个改动点:

  • 引入了超时机制,协调者与参与者都引入了超时机制。
  • 引入准备阶段 ,检查是否可以执行事务,或业务是否满足均可。

一阶段 (CanCommit) :

  • **询问事务 ** 是否可以提交,也就是说访问的数据此时是否被其他事务访问,而无法自己无法开启新的事务。
  • 业务是否满足等,如转账业务余额是否足够等。

二阶段(PreCommit):

  • 该阶段参与者执行我们具体的业务代码,也就是事务内的操作,观察是否可以正常执行。
  • 并将undoredo信息记录到事务日志中,若出现异常进行回滚。
  • 最终响应给协调者成功或失败的信息。

该阶段有一下几种可能:

  1. 正常执行,所有参与者都返回success信息,则协调者进入下一阶段提交阶段。
  2. 某个参与者回馈fail或超时,协调者直接发送放弃操作。

三阶段(doCommit):

该阶段进行真正的事务提交,协调者向参与者发送commit通知,参与者开始真正的事务提交,执行完之后返回事务执行结果。

有以下几种情况:

  1. 所有参与者均提交事务成功,则正常执行反馈给协调者事务结果即可。
  2. 部分参与者失败或参与者超时未反馈给协调者,则协调者对所有参与者发送rollback操作,根据前面保存的日志进行回滚。
  3. 协调者发送参与者消息(commit或rollback)失败,则参与者会默认commit,因为二阶段已经验证事务操作正常,所以这儿大概率会成功,但也有可能造成数据不一致的情况。

3、XA规范

XA 事务的基础是两阶段提交协议。需要有一个事务协调者来保证所有的事务参与者都完成了准备工作(第一阶段)。如果协调者收到所有参与者都准备好的消息,就会通知所有的事务都可以提交了(第二阶段)。

4、TCC模式

TCC:Try(预处理)、Confirm(确认)、Cancel(取消)

  • Try阶段:主要是对业务系统做检测及资源预留,如转账业务查询余额是否充足。
  • Confirm阶段:主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。如果confirm出错了,那么就需要引入补偿机制或者人工处理。
  • Cancel阶段:主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。同样TCC中我们认为cancel阶段一定会执行成功,如果失败也需要引入重试或者人工处理。

当然上述操作要保证幂等性

具体可参考另一篇博客:https://blog.csdn.net/zhengguofeng0328/article/details/124423358

5、本地消息表

流程图如下所示:

在这里插入图片描述

  • 1.1 正常写入数据库
  • 1.2 在写入数据库的同时,写入一张本地消息表。这张表,用来记录MQ消息处理的状态,可以有发送中和已完成两种状态。由于消息表和正常的业务表在一个DB中,所以可以达成本地事务,确保同时完成
  • 2 写入消息表成功之后,可以异步发送MQ消息,且不用关心投递是否成功
  • 3 后续业务订阅MQ消息。消费成功之后,将会把执行成功的状态,再通过MQ来发送。本地业务订阅这个执行状态,并把消息表中对应的记录状态,改为已完成;如果消费失败,则不做过多处理
  • 4 存在一个定时任务,持续扫描本地消息表中,状态为发送中的消息(注意延时),并再次把这些消息发送到MQ,重复2的过程

当然这只保证最终一致性

6、MQ事务方案(可靠消息事务)

在这里插入图片描述

与本地消息表类似,只不过把日志消息从数据库移到了MQ中,进行消费消息即可。

  1. A正常写入数据,以及将回滚消息与B参与者的事务消息发送到MQ中,由B消费。
  2. B消费后将success或fail消息发送到MQ中去,返回处理结果。
  3. A收到B反馈的消息若成功则结束,若失败A从MQ中获取回滚消息进行数据回滚。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值