乐趣区

关于分布式:架构设计-基于电商交易流程图解TCC事务分段提交

本文源码:GitHub·点这里 || GitEE·点这里

一、场景案例简介

1、场景形容

分布式事务在业务零碎中是非常常见的,最经典的场景就是电商架构中的交易业务,如图:

客户端通过申请订单服务,执行下单操作,实际上从订单服务上又触发了多个服务链申请,根本步骤如下:

  • 客户端申请在订单服务上创立订单;
  • 订单服务调用账户服务扣款;
  • 订单服务调用库存服务执行库存扣减;
  • 订单通过物流服务,转化为物流运单;

这套流程在电商零碎中是根本业务,在理论的开发中远比这里形容的简单。

2、服务时序图

上述 1 中是业务性的流程概念形容,从零碎开发层面,在微服务的架构模式下,通常的时序流如下:

这样服务间的通信时序图在程序设计中非常常见,在分布式系统中,分明的形容各个服务间的通信流程是非常要害的。

上图形容的交易流程是在最现实的状态下,各个服务都执行胜利,然而程序是不能 100% 保障始终失常,经常出现如下状况:

  • 服务间通信失败;
  • 单个节点服务宕掉;
  • 服务接口执行失败;

这些都是理论开发中经常出现的问题,比方订单创立胜利,扣款胜利,然而库存扣减失败,物流运单生成,那么这笔订单该如何解决?这就是分布式事务要解决的外围问题。

分布式事务机制要保障不同服务之间造成一个整体性的可控的事务,业务流程上的服务除非全副胜利,否则任何服务的操作失败,都会导致所有服务上操作回滚,撤销曾经实现的动作。

二、TCC 根底概念

1、分段提交协定

XA 是一个分布式事务协定,大抵分为两局部:事务管理器和本地资源管理器,本地资源管理器根本由数据库实现,大多数关系型数据库都实现 XA 接口,而事务管理器作为全局事务的调度者,负责整个事务中本地资源的提交和回滚,基本原理如下:

阶段 1:事务询问

事务管理器向所有的参加事务的资源管理器发送确认申请,询问是否能够执行事务提交操作,并期待各参与者的响应,如果执事务操作胜利,就反馈给事务管理器示意事务能够执行,如果没有胜利执行事务,就反馈事务不能够执行;

阶段 2:事务提交

XA 依据第一阶段每个资源管理器是否都筹备提交胜利,判断是要事务整体提交还是回滚,正式执行事务提交操作,并在实现提交之后开释整个事务占用的资源;事务也会存在失败状况,导致流程勾销回滚;

XA 事务具备强一致性,在两阶段提交的整个过程中,始终会持有资源的锁,性能不现实的毛病很显著,特地是在交易下单链路中,往往并发量很高,XA 无奈满足该类高并发场景。

2、TCC 概念简介

Try(预处理)-Confirm(确认)-Cancel(勾销)模式的简称 TCC。

Try 阶段

业务查看 (一致性) 及资源预留(隔离),该阶段是一个初步操作,提交事务前的查看及预留业务资源实现;例如购票零碎中的占位胜利,须要在 15 分钟内领取;

Confirm 阶段

确认执行业务操作,不在执行任何业务查看,基于 Try 阶段预留的业务资源,从现实状态下看只有 Try 胜利,Confirm 也会胜利,因为资源的检查和锁定都曾经胜利;该阶段呈现问题,须要重试机制或者手动解决;购票零碎中的占位胜利并且 15 分钟内领取实现,购票胜利;

Cancel 阶段

Cancel 阶段是在业务执行谬误须要回滚到状态下执行分支事务的勾销,预留资源的开释;购票零碎中的占位胜利然而 15 分钟内没有领取,勾销占位;

3、TCC 比照 XA

XA 事务的强一致性,导致资源层的锁定;

TCC 在业务层面谋求最终一致性,不会短暂占用资源;

三、分段事务剖析

当初回到模块一中的场景案例,在现实状态下流程全副胜利是好的,但理论状况是突发状况很多,基于 TCC 模式分析上述电商的具体业务:

1、资源预留

在 TCC 模式下,通常表字段的状态设计思路为:订单(领取中. 已领取. 勾销订单),账户(金额. 解冻金额),库存(库存. 解冻库存),物流(出库中. 已出库,已撤回),这种状态治理在开发中十分常见。

所以在 TCC 模式里通常会如下解决资源预留:

假如订单总额为:200,状态:领取中,则此时资源预留状况如下:

  • tc_account 账户表:tc_total=1000,tc_ice=200,总金额 1000,解冻 200;
  • tc_inventory 库存表:tc_total=100,tc_ice=20,总库存 100 件,解冻 20 件;
  • tc_waybill 运单表:tc_state=1,运单状态,出库中;

这样下单链路上的相干资源已查看并且预留胜利;

2、资源提交确认

资源预留胜利之后,执行资源提交执行:

  • tc_account 账户表:tc_total=800,tc_ice=0,即订单扣款胜利;
  • tc_inventory 库存表:tc_total=80,tc_ice=0,库存消减胜利;
  • tc_waybill 运单表:tc_state=2,运单状态,已出库;

这样下单链路上的相干资源已全副提交解决胜利,这是最现实的状态;

3、失败回滚

整个过程是可能执行失败的,或者用户间接本人发动回退,则要回滚整个链路上的数据:

  • tc_account 账户表:tc_total=1000,tc_ice=0,勾销账户解冻的 200;
  • tc_inventory 库存表:tc_total=100,tc_ice=0,勾销库存解冻的 20 件;
  • tc_waybill 运单表:tc_state=3,运单状态,已撤回;

这样下单链路上的相干数据都基于该笔订单做回退操作,复原;

4、弥补机制

整个电商交易流程,不论是胜利,还是残缺的回退失败,都是须要在现实状态下,要求整个服务链路和数据是相对失常的才行。然而在理论分布式架构下是很难保障的,所以在产品的设计上会预留很多操作入口,用来手动做事务弥补或回退操作:

大型简单的业务零碎中,间接批改数据库通常状况下是不容许的,个别外围流程会预留各种操作入口,用来解决突发状况,补救数据的完整性,例如交易链路上,只有扣款胜利,后续的数据无论如何都会补上,是不容许回滚的,当然如果没有扣款胜利,订单有效期完结,该笔交易也就算做完结。

5、写在最初

通过电商交易的案例,和 TCC 模式的概念,形容了分布式事务的流程和解决思路,在开发时通常会抉择现有的分布式组件来具体实现事务管制,这个流程后续再聊。

四、源代码地址

GitHub·地址
https://github.com/cicadasmile/data-manage-parent
GitEE·地址
https://gitee.com/cicadasmile/data-manage-parent

举荐浏览:架构设计

序号 题目
00 架构设计:单服务. 集群. 分布式,根本区别和分割
01 架构设计:分布式业务零碎中,全局 ID 生成策略
02 架构设计:分布式系统调度,Zookeeper 集群化治理
03 架构设计:接口幂等性准则,防反复提交 Token 治理
04 架构设计:缓存管理模式,监控和内存回收策略
05 架构设计:异步解决流程,多种实现模式详解
06 架构设计:高并发流量削峰,共享资源加锁机制
07 架构设计:分布式服务,库表拆分模式详解
08 架构设计:分布式事务①概念简介和基础理论
退出移动版