- 主业务服务:主业务服务负责发起并完成整个业务活动 。
- 从业务服务:从业务服务是整个业务活动的参与方,实现 Try、Confirm、Cancel 操作,供主业务服务调用 。
- 业务活动管理器:业务活动管理器管理控制整个业务活动,包括记录事务状态,调用从业务服务的 Confirm 操作,调用从业务服务的 Cancel 操作等 。
TCC 的 Try 阶段:
- 生成一条订单记录,订单状态为待确认 。
- 将用户 A 的账户金币中余额更新为 90,冻结金币为 10(预留业务资源) 。
- 将用户的礼物数量为 5,预增加数量为 10 。
- Try 成功之后,便进入 Confirm 阶段 。
- Try 过程发生任何异常,均进入 Cancel 阶段 。

文章插图
TCC 的 Confirm 阶段:
- 订单状态更新为已支付 。
- 更新用户余额为 90,可冻结为 0 。
- 用户礼物数量更新为 15,预增加为 0 。
- Confirm 过程发生任何异常,均进入 Cancel 阶段 。
- Confirm 过程执行成功,则该事务结束 。

文章插图
TCC 的 Cancel 阶段:
- 修改订单状态为已取消 。
- 更新用户余额回 100 。
- 更新用户礼物数量为 5 。

文章插图
TCC 方案让应用可以自定义数据库操作的粒度,降低了锁冲突,可以提升性能 。
但是也有以下缺点:
- 应用侵入性强,Try、Confirm、Cancel 三个阶段都需要业务逻辑实现 。
- 需要根据网络、系统故障等不同失败原因实现不同的回滚策略,实现难度大,一般借助 TCC 开源框架,ByteTCC,TCC-transaction,Himly 。
eBay 最初提出本地消息表这个方案,来解决分布式事务问题 。业界目前使用这种方案是比较多的,它的核心思想就是将分布式事务拆分成本地事务进行处理 。
可以看一下基本的实现流程图:

文章插图
基本实现思路如下 。
发送消息方:
- 需要有一个消息表,记录着消息状态相关信息 。
- 业务数据和消息表在同一个数据库,即要保证它俩在同一个本地事务 。
- 在本地事务中处理完业务数据和写消息表操作后,通过写消息到 MQ 消息队列 。
- 消息会发到消息消费方,如果发送失败,即进行重试 。
- 处理消息队列中的消息,完成自己的业务逻辑 。
- 此时如果本地事务处理成功,则表明已经处理成功了 。
- 如果本地事务处理失败,那么就会重试执行 。
- 如果是业务上面的失败,给消息生产方发送一个业务补偿消息,通知进行回滚等操作 。
优缺点:该方案的优点是很好地解决了分布式事务问题,实现了最终一致性 。缺点是消息表会耦合到业务系统中 。
最大努力通知
什么是最大通知?最大努力通知也是一种分布式事务解决方案 。

文章插图
下面是企业网银转账一个例子:
- 企业网银系统调用前置接口,跳转到转账页 。
- 企业网银调用转账系统接口 。
- 转账系统完成转账处理,向企业网银系统发起转账结果通知,若通知失败,则转账系统按策略进行重复通知 。
- 企业网银系统未接收到通知,会主动调用转账系统的接口查询转账结果 。
- 转账系统会遇到退汇等情况,会定时回来对账 。
最大努力通知实现机制如下:

文章插图
最大努力通知解决方案:要实现最大努力通知,可以采用 MQ 的 ACK 机制 。
推荐阅读
- 日常这六件事能招来猝死!不知道的人赶紧看看
- 原理篇 分布式系统中如何优雅地追踪日志
- 分布式系统ID的生成方法之UUID、数据库、算法、Redis、Leaf方案
- 分布式系统架构落地与瓶颈突破 进阶架构师必读,人人都是架构师
- 汽车补胎是常事,但是车主却不知道哪种补胎好,修理工告诉你
- 公积金不买房屋就没用了?大多数人不知道,这4种情况也可以使用
- 黄茶的功效与作用喝了这么久竟然不知道,黄茶的功效与作用及禁忌详解
- 洗发水|曝光黑名单,几十款垃圾洗发水上榜,但很多家庭却不知道!
- 还不知道你的社保账户有多少钱?赶紧查一查
- 太极中的三不动技巧 你绝对不知道
