分布式事务 中间件 Seata 源码分析 08 TCC 模式实现

TCC 原理图如下

分布式事务 中间件 Seata 源码分析 08 TCC 模式实现_第1张图片

分为如下几步

1.业务方调用各个微服务的try()方法,执行资源检查及预留操作
2.当所有try()方法均执行成功时,对全局事务进行提交,即由事务管理器调用每个微服务的confirm()方法
当任意一个方法try()失败(预留资源不足,抑或网络异常,代码异常等任何异常),由事物管理器调用每个微服务的cancle()方法对全局事务进行回滚
try(),  confirm()和cancel()方法,都需要业务方自己实现

先看下TCC的示例samples

业务调用方,通过GlobalTransactional注解开启事务,并调用各个服务提供方的try()方法

å¨è¿éæå¥å¾çæè¿°

服务提供方

TwoPhaseBusinessAction注解标记这是个TCC接口,同时指定commitMethod,rollbackMethod的名称
BusinessActionContext是TCC事务中的上下文对象
BusinessActionContextParameter注解标记的参数会在上下文中传播,即能通过BusinessActionContext对象在commit方法及cancle方法中取到该参数值

å¨è¿éæå¥å¾çæè¿°

一、先看下全局GlobalTransactionScanner 的wrapIfNessary方法

从配置中获取,如果disableGlobalTransaction是生效的,直接return 返回

分布式事务 中间件 Seata 源码分析 08 TCC 模式实现_第2张图片

1.对bean进行反射解析,获取方法上面的annotation,判断是否为一个tcc的bean,如果是tcc的proxy,就创建一个TccActionInterceptor拦截器

二、开启TCC全局事务

TCC模式业务调用方和AT模式一样,需要使用GlobalTransactional注解来开启全局事务

业务方法执行时,最终会被GlobalTransactionalInterceptor拦截,开启一个全局事务,获得全局事务id,即xid

代码如下图

分布式事务 中间件 Seata 源码分析 08 TCC 模式实现_第3张图片

先执行事务模板的方法,调用transactionalTemplate.execute

分布式事务 中间件 Seata 源码分析 08 TCC 模式实现_第4张图片

执行方法execute

1.获取或者创建一个全局globalTransaction

分布式事务 中间件 Seata 源码分析 08 TCC 模式实现_第5张图片

2.调用getTransactionInfo,获取事务信息

   2.1 循环globalTransaction的回滚方法,包装为rollbackRules,填充到事务信息transactionInfo,并且校验事务信息不为空

 3.调用beginTransaction,开启事务

分布式事务 中间件 Seata 源码分析 08 TCC 模式实现_第6张图片

1.transactionManager.begin(null, null, name, timeout);  通过tmRpcClient,同步调用,底层通过channel发送请求,并且获取应答response,从中获取xid

2.然后rootContext绑定这个全局xid

3.执行业务逻辑business

4.执行出现异常,就回滚

分布式事务 中间件 Seata 源码分析 08 TCC 模式实现_第7张图片

本质上还是通过channel,同步调用tc,返回response

5.如果没有出现异常,就tx调用commit提交全局事务

 分为几步

  1. 根据xid取出GlabalSession
  2. 关闭Session,防止再有分支注册尽量
  3. 修改状态为提交中
  4. 如果可以异步提交,则异步提交,否则同步提交,TCC类型,只能同步提交

6.最后触发事务完成的操作,调用triggerAfterCompletion()

   

总结一下全局事务提交的大致流程

业务方调用微服务无异常,通过TM发起事务提交请求
TC接收到事务提交请求后,通过Xid找到全局事务,再取出所有的分支事务
遍历分支事务,发出分支事务提交请求
TCC资源管理器RM接收到提交请求后,从本地TCCResource缓存中根据resourceId取出对应方法bean,反射调用commit方法
 

 

    

 

 

你可能感兴趣的:(分布式事务)