seata源码分析-AT模式-开启全局事务

导读

分布式事务模式:AT
分布式调用场景:
1、客户端请求Business服务下单----》
2、Business通过Rpc调用Storage服务扣减库存----》
3、Business通过Rpc调用Order服务创建订单-----》
4、Order通过Rpc调用Account服务扣减用户余额

模块调用逻辑架构
在这里插入图片描述
代码结构
在这里插入图片描述

模块名称 模块描述
samples-business 分布式事务入口(TM)
samples-account 账户服务(RM)
samples-order 订单服务(RM)
samples-storage 库存服务(RM)
samples-common 公共模块

源码分析

源码分析需要拆分两部分来说明
1、项目启动时,seata客户端做了哪些准备工作?
2、客户端请求Business服务下单,seata客户端请求服务端开启全局事务是怎么实现的呢?

1 解析seata客户端初始化

1.1.1、初始化全局事务扫描器(GlobalTransactionScanner)
1.1.2、初始化TM Client,RM Client
1.1.3、生成代理类对象

1.1、初始化全局事务扫描器(GlobalTransactionScanner)

找到GlobalTransaction自动配置类
在这里插入图片描述
初始化扫描器类对象

@Configuration
@EnableConfigurationProperties({
   SeataProperties.class})
public class GlobalTransactionAutoConfiguration {
   
    private final ApplicationContext applicationContext;
    private final SeataProperties seataProperties;
    public GlobalTransactionAutoConfiguration(ApplicationContext applicationContext, SeataProperties seataProperties) {
   
        this.applicationContext = applicationContext;
        this.seataProperties = seataProperties;
    }
    @Bean
    public GlobalTransactionScanner globalTransactionScanner() {
   
        String applicationName = this.applicationContext.getEnvironment().getProperty("spring.application.name");
        String txServiceGroup = this.seataProperties.getTxServiceGroup();
        if (StringUtils.isEmpty(txServiceGroup)) {
   
            txServiceGroup = applicationName + "-fescar-service-group";
           this.seataProperties.setTxServiceGroup(txServiceGroup);
        }
        return new GlobalTransactionScanner(applicationName, txServiceGroup);
    }
}

通过扫描器类发现继承,实现关系
在这里插入图片描述

1.2、初始化TM Client,RM Client

通过InitializingBean接口,实现afterPropertiesSet
初始化TM、RM客户端

 @Override
    public void afterPropertiesSet() {
   
        if (disableGlobalTransaction) {
   
            if (LOGGER.isInfoEnabled()) {
   
                LOGGER.info("Global transaction is disabled.");
            }
            return;
        }
        initClient();
    }

初始化TM、RM netty客户端

private void initClient() {
   
        if (LOGGER.isInfoEnabled()) {
   
            LOGGER.info("Initializing Global Transaction Clients ... ");
        }
        if (StringUtils.isNullOrEmpty(applicationId) || StringUtils.isNullOrEmpty(txServiceGroup)) {
   
            throw new IllegalArgumentException(String.format("applicationId: %s, txServiceGroup: %s", applicationId, txServiceGroup));
        }
        //init TM
        TMClient.init(applicationId, txServiceGroup);
        if (LOGGER.isInfoEnabled()) {
   
            LOGGER.info("Transaction Manager Client is initialized. applicationId[{}] txServiceGroup[{}]", applicationId, txServiceGroup);
        }
        //init RM
        RMClient.init(applicationId, txServiceGroup);
        if (LOGGER.isInfoEnabled()) {
   
            LOGGER.info("Resource Manager is initialized. applicationId[{}] txServiceGroup[{}]", applicationId, txServiceGroup);
        }
        if (LOGGER.isInfoEnabled()) {
   
            LOGGER.info("Global Transaction Clients are initialized. ");
        }
        registerSpringShutdownHook();
    }

registerSpringShutdownHook钩子函数,在Spring容器停止的时候关闭Netty连接

1.3、生成代理类对象

GlobalTransactionScanner通过继承AbstractAutoProxyCreator
重写wrapIfNecessary方法实现代理

@Override
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   
        if (disableGlobalTransaction) {
   
            return bean;
        }
        try {
   
            synchronized (PROXYED_SET) {
   
                if (PROXYED_SET.contains(beanName)) {
   
                    return bean;
                }
                interceptor = null;
                //check TCC proxy
                if (TCCBeanParserUtils.isTccAutoProxy(bean, beanName, applicationContext)) {
   
                    //TCC interceptor, proxy bean of sofa:reference/dubbo:reference, and LocalTCC
                    interceptor = new TccActionInterceptor(TCCBeanParserUtils.getRemotingDesc(beanName));
                } else {
   
                    Class<?> serviceInterface = SpringProxyUtils.findTargetClass(bean);
                    Class<?>[] interfacesIfJdk = SpringProxyUtils.findInterfaces(bean);

                    if (!existsAnnotation(new Class[]{
   serviceInterface})
                        && !existsAnnotation(interfacesIfJdk)) {
   
                        return bean;
                    }

                    if (interceptor == null) {
   
                        interceptor = new GlobalTransactionalInterceptor(failureHandlerHook);
                        ConfigurationFactory.
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值