微服务分布式事务-TCC模式
一个完整的 TCC 业务由一个主业务服务和若干个从业务服务组成,主业务服务发起并完成整个业务活动,TCC 模式要求从服务提供三个接口:Try、Confirm、Cancel。
1. Try
1)完成所有业务检查;
2)预留必须业务资源。
2. Confirm
1)真正执行业务
2)不作任何业务检查
3)只使用 Try 阶段预留的业务资源
4)Confirm 操作满足幂等性
3. Cancel
1)释放 Try 阶段预留的业务资源
2)Cancel 操作满足幂等性
3)整个 TCC 业务分成两个阶段完成:
- 第一阶段:主业务服务分别调用所有从业务的 try 操作,并在活动管理器中登记所有从业务服务。当所有从业务服务的 try
操作都调用成功或者某个从业务服务的 try 操作失败,进入第二阶段。 - 第二阶段:活动管理器根据第一阶段的执行结果来执行 confirm 或 cancel 操作。
如果第一阶段所有 try 操作都成功,则活动管理器调用所有从业务活动的 confirm操作。否则调用所有从业务服务的 cancel 操作。
需要注意的是,第二阶段 confirm 或 cancel 操作本身也是满足最终一致性的过程,在调用 confirm 或 cancel 的时候也可能因为某种原因(比如网络)导致调用失败,所以需要活动管理支持重试的能力,同时这也就要求 confirm 和 cancel 操作具有幂等性。
在补偿模式中一个比较明显的缺陷是,没有隔离性。从第一个工作服务步骤开始一直到所有工作服务完成(或者补偿过程完成),不一致是对其他服务可见的。另外最终一致性的保证还充分的依赖了协调服务的健壮性,如果协调服务异常,就没法达到一致性。
TCC模式在一定程度上弥补了上述的缺陷,在TCC模式中直到明确的confirm动作,所有的业务操作都是隔离的(由业务层面保证)。另外工作服务可以通过指定 try 操作的超时时间,主动的 cancel 预留的业务资源,从而实现自治的微服务。
TCC模式和补偿模式一样需要需要有协调服务和工作服务,协调服务也可以作为通用服务一般实现为框架。与补偿模式不同的是 TCC 服务框架不需要记录详细的业务流水,完成 confirm 和 cancel 操作的业务要素由业务服务提供。
在第4步确认预订之前,订单只是pending状态,只有等到明确的confirm之后订单才生效。
如果3个服务中某个服务try操作失败,那么可以向TCC服务框架提交cancel,或者什么也不做由工作服务自己超时处理。
TCC 模式也不能百分百保证一致性,如果业务服务向 TCC 服务框架提交 confirm后,TCC 服务框架向某个工作服务提交 confirm 失败(比如网络故障),那么就会出现不一致,一般称为 heuristic exception。
需要说明的是,为保证业务成功率,业务服务向 TCC 服务框架提交 confirm 以及TCC 服务框架向工作服务提交 confirm/cancel 时都要支持重试,这也就要confirm/cancel 的实现必须具有幂等性。如果业务服务向 TCC 服务框架提交confirm/cancel 失败,不会导致不一致,因为服务最后都会超时而取消。
另外 heuristic exception 是不可杜绝的,但是可以通过设置合适的超时时间,以及重试频率和监控措施使得出现这个异常的可能性降低到很小。如果出现了heuristic exception 是可以通过人工的手段补救的。
对账是最后的终极防线!!!
如果有些业务由于瞬时的网络故障或调用超时等问题,通过上文所讲的 3 种模式一般都能得到很好的解决。但是在当今云计算环境下,很多服务是依赖于外部系统的可用性情况,在一些重要的业务场景下还需要周期性的对账来保证真实的一致性。比如支付系统和银行之间每天日终是都会有对账过程。