seata源码分析之全局事务的开启跟xid的传递

本文分析了Seata全局事务的开启过程,从@GlobalTransactional注解开始,通过GlobalTransactionScanner和GlobalTransactionalInterceptor的角色,详细解释了如何创建代理对象并拦截方法调用。在事务开始时,GlobalTransaction的init和begin方法被调用,同时通过TransactionHookManager注册的hook可以在事务开始前后执行自定义操作。XID的传递主要在SeataFeignClient中完成,将XID放入请求头传递给下游服务,并通过SeataHandlerInterceptor在Spring MVC的拦截器链中捕获和使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概览

首先我们通过@GlobalTransactional这个注解开启一个全局事务,而GlobalTransactionScanner.wrapIfNecessary()会为所有方法上加了这个注解的bean注入一个包装了GlobalTransactionalInterceptor实例的advisor,然后返回一个代理对象。GlobalTransactionalInterceptor会在该bean的方法调用前进行拦截,判断是否开启全局事务

上源码,关键位置我打了注释

@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);

                //判断bean里的方法上有没有@GlobalTransactional注解
                if (!existsAnnotation(new Class[]{serviceInterface})
                    && !existsAnnotation(interfacesIfJdk)) {
                    return bean;
                }

                if (interceptor == null) {
                    //初始化Interceptor,后面会注入代理对象
                    interceptor = new GlobalTransactionalInterceptor(failureHandlerHook);
                    ConfigurationFactory.getInstance().addConfigListener(ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION, (ConfigurationChangeListener) interceptor);
                }
            }
            
            //判断当前bean是否已被aop代理过,比如说方法上加了@Transactional就会被spring代理
            //如果没有被代理,调用父类的模板方法进行代理,advisor通过被重写的
            //getAdvicesAndAdvisorsForBean返回上面的interceptor进行包装
            if (!AopUtils.isAopProxy(bean)) {
                bean = super.wrapIfNecessary(bean, beanName, cacheKey);
            } else {
                AdvisedSupport advised = SpringProxyUtils.getAdvisedSupport(bean);

                //把GlobalTransactionalInterceptor包装成advisor
                Advisor[] advisor = buildAdvisors(beanName, getAdvicesAndAdvisorsForBean(null, null, null));
                for (Advisor avr : advisor) {
                    advised.addAdvisor(0, avr);
                }
            }
            PROXYED_SET.add(beanName);
            return bean;
        }
    } catch (Exception exx) {
        throw new RuntimeException(exx);
    }
}


@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName,          
  TargetSource customTargetSource) throws BeansException {

    //返回interceptor[]
    return new Object[]{interceptor};
}

@Override
    public void afterPropertiesSet() {
        if (disableGlobalTransaction) {
            if (LOGGER.isInfoEnabled()) {
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值