TCC事务

x33g5p2x  于2022-03-13 转载在 其他  
字(1.3k)|赞(0)|评价(0)|浏览(375)

一 点睛

TCC 事务是“Try-Confirm-Cancel”三个单词的缩写。

可靠性消息队列虽然能够保证最终结果的相对可靠性,过程也足够简单,但整个过程完全没有任何隔离性可言,虽然在一些业务中隔离性是无关紧要的,但在有些业务中缺乏隔离性就会带来许多麻烦。例如,缺乏隔离性就会带来的一个明显问题便是“超售”:如两个客户在短时间内都成功购买了同一件商品,而且他们各自购买的数量都不超过目前的库存,但他们购买的数量之和却超过了库存。如果这件事情属于刚性需求,且隔离级别足够时是可以完全避免的。例如,上面这个场景就需要“可重复读”的隔离级别,以保证后面提交的事务会因为无法获得锁而导致失败,但用可靠消息队列就无法保证这一点。如果业务需要隔离,那架构师通常就应该重点考虑 TCC 方案,该方案天生适用于需要强隔离性的分布式事务中。

二 具体实现过程

TCC 较为繁琐,它是一种业务侵入式较强的事务方案,要求业务处理过程必须拆分为“预留业务资源”和“确认/释放消费资源”两个子过程。如同 TCC 的名字所示,它分为以下三个阶段。

Try:尝试执行阶段,完成所有业务可执行的检查(保障一致性),并且预留好全部需要用到的业务资源(保障隔离性)。

Confirm:确认执行阶段,不进行任何业务检查,直接使用 Try 阶段准备的资源来完成业务处理。Confirm 阶段可能会重复执行,因此本阶段执行的操作需要具备幂等性。

Cancel:取消执行阶段,释放 Try 阶段预留的业务资源。Cancel 阶段可能会重复执行,因此本阶段执行的操作也需要具备幂等性。

三 案例说明

1 最终用户向书店发送交易请求,购买一本价值为 100 元的书。

2 创建事务,生成事务 ID,记录在活动日志中,进入 Try 阶段。

  • 用户服务:检查业务可性性,若可行,将该用户的 100 元设置为“冻结”状态,通知下一步进入 Confirm 阶段;若不可行,通知下一步进入 Cancel 阶段。
  • 仓库服务:检查业务可性性,若可行,将仓库中的这本书设置为“冻结”状态,通知下一步进入 Confirm 阶段;若不可行,通知下一步进入 Cancel 阶段。
  • 商家服务:检查业务可行性,不需要冻结资源。

3 如果第2步所有业务均反馈业务可行,将活动日志中的状态记录为 Confirm,进入 Confirm 阶段。

  • 用户服务:完成业务操作(扣减被冻结的 100 元)。
  • 仓库服务:完成业务操作(标记那1本冻结的书为出库状态,扣减相应库存)。
  • 商家服务:完成业务操作(收款100元)。

4 第3步如果全部完成,事务正常结束,如果第3步中任何一方出现异常,不论是业务异常还是网络异常,都将根据活动日志中的记录,重复执行服务的 Confirm 操作,即进行最大努力交付。

5 如果第2步中有任意一方反馈业务不可行,或任意一方超时,则将活动日志的状态记录为 Cancel,进入 Cancel 阶段。

  • 用户服务:取消业务操作(释放被冻结的 100 元)。
  • 仓库服务:取消业务操作(释放被冻结的1本书)。
  • 商家服务:取消业务操作。

6 第5步如果全部完成,事务宣告以失败回滚结束,如果第5步中任何一方出现异常,不论是业务异常还是网络异常,都将根据活动日志中的记录,重复执行该服务的 Cancel 操作,即进行最大努力交付。

相关文章