spring cloud seata 使用说明


spring cloud seata 使用说明

 

*****************************

自动配置类

 

SeataAutoConfiguration

@ComponentScan(basePackages = {"io.seata.spring.boot.autoconfigure.properties"})
@ConditionalOnProperty(
    prefix = "seata",
    name = {"enabled"},
    havingValue = "true",
    matchIfMissing = true
)
@Configuration
@EnableConfigurationProperties({SeataProperties.class})
public class SeataAutoConfiguration {
    private static final Logger LOGGER = LoggerFactory.getLogger(SeataAutoConfiguration.class);
    @Autowired
    private SeataProperties seataProperties;

    public SeataAutoConfiguration() {
    }

    @Bean
    public SpringUtils springUtils() {
        return new SpringUtils();
    }

    @Bean
    @DependsOn({"springUtils"})
    @ConditionalOnMissingBean({GlobalTransactionScanner.class})
    public GlobalTransactionScanner globalTransactionScanner() {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("Automatically configure Seata");
        }

        return new GlobalTransactionScanner(this.seataProperties.getApplicationId(), this.seataProperties.getTxServiceGroup());
    }
}

 

SeataProperties:seata配置属性

@Component
@ConfigurationProperties(prefix = "seata")
@EnableConfigurationProperties({SpringCloudAlibabaConfiguration.class})
public class SeataProperties {
    private boolean enabled = true;
    private String applicationId;
    private String txServiceGroup;
    @Autowired
    private SpringCloudAlibabaConfiguration springCloudAlibabaConfiguration;

    public SeataProperties() {
    }

    public boolean isEnabled() {
        return this.enabled;
    }

    public SeataProperties setEnabled(boolean enabled) {
        this.enabled = enabled;
        return this;
    }

    public String getApplicationId() {
        if (null == this.applicationId) {
            this.applicationId = this.springCloudAlibabaConfiguration.getApplicationId();
        }//如果没有设置,默认去springCloudAlibanaConfiguration中的applicationId值

        return this.applicationId;
    }

    public SeataProperties setApplicationId(String applicationId) {
        this.applicationId = applicationId;
        return this;
    }

    public String getTxServiceGroup() {
        if (null == this.txServiceGroup) {
            this.txServiceGroup = this.springCloudAlibabaConfiguration.getTxServiceGroup();
        }//如果没有设置,默认去springCloudAlibanaConfiguration中的txServiceGroup值

        return this.txServiceGroup;
    }

    public SeataProperties setTxServiceGroup(String txServiceGroup) {
        this.txServiceGroup = txServiceGroup;
        return this;
    }
}

 

SpringCloudAlibabaConfiguration:配置applicationId、txServiceGroup属性

@ConfigurationProperties(prefix = "spring.cloud.alibaba.seata")
public class SpringCloudAlibabaConfiguration implements ApplicationContextAware {
    private static final Logger LOGGER = LoggerFactory.getLogger(SpringCloudAlibabaConfiguration.class);
    private static final String SPRING_APPLICATION_NAME_KEY = "spring.application.name";
    private static final String DEFAULT_SPRING_CLOUD_SERVICE_GROUP_POSTFIX = "-seata-service-group";
    private String applicationId;
    private String txServiceGroup;
    private ApplicationContext applicationContext;

    public SpringCloudAlibabaConfiguration() {
    }

    public String getApplicationId() {
        if (null == this.applicationId) {
            this.applicationId = this.applicationContext.getEnvironment().getProperty("spring.application.name");
        }//如果没有设置,默认为spring.application.name的值

        return this.applicationId;
    }

    public String getTxServiceGroup() {
        if (null == this.txServiceGroup) {
            String applicationId = this.getApplicationId();
            if (null == applicationId) {
                LOGGER.warn("{} is null, please set its value", "spring.application.name");
            }

            this.txServiceGroup = applicationId + "-seata-service-group";
        }//如果没有设置,默认为spring.application.name的值+"-seata=service-group"

        return this.txServiceGroup;
    }

    public void setTxServiceGroup(String txServiceGroup) {
        this.txServiceGroup = txServiceGroup;
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

 

GlobalTransactionScanner:全局事务扫描

public class GlobalTransactionScanner extends AbstractAutoProxyCreator implements InitializingBean, ApplicationContextAware, DisposableBean {
    private static final long serialVersionUID = 1L;
    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalTransactionScanner.class);
    private static final int AT_MODE = 1;
    private static final int MT_MODE = 2;
    private static final int ORDER_NUM = 1024;
    private static final int DEFAULT_MODE = 3;
    private static final Set PROXYED_SET = new HashSet();
    private static final FailureHandler DEFAULT_FAIL_HANDLER = new DefaultFailureHandlerImpl();
    private MethodInterceptor interceptor;
    private final String applicationId;
    private final String txServiceGroup;
    private final int mode;
    private final boolean disableGlobalTransaction;
    private final FailureHandler failureHandlerHook;
    private ApplicationContext applicationContext;

    public GlobalTransactionScanner(String txServiceGroup) {
        this(txServiceGroup, txServiceGroup, 3);
    }

    public GlobalTransactionScanner(String txServiceGroup, int mode) {
        this(txServiceGroup, txServiceGroup, mode);
    }

    public GlobalTransactionScanner(String applicationId, String txServiceGroup) {
        this(applicationId, txServiceGroup, 3);
    }

    public GlobalTransactionScanner(String applicationId, String txServiceGroup, int mode) {
        this(applicationId, txServiceGroup, mode, DEFAULT_FAIL_HANDLER);
    }

    public GlobalTransactionScanner(String applicationId, String txServiceGroup, FailureHandler failureHandlerHook) {
        this(applicationId, txServiceGroup, 3, failureHandlerHook);
    }

    public GlobalTransactionScanner(String applicationId, String txServiceGroup, int mode, FailureHandler failureHandlerHook) {
        this.disableGlobalTransaction = ConfigurationFactory.getInstance().getBoolean("service.disableGlobalTransaction", false);
        this.setOrder(1024);
        this.setProxyTargetClass(true);
        this.applicationId = applicationId;
        this.txServiceGroup = txServiceGroup;
        this.mode = mode;
        this.failureHandlerHook = failureHandlerHook;
    }

    public void destroy() {
        ShutdownHook.getInstance().destroyAll();
    }

    private void initClient() {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("Initializing Global Transaction Clients ... ");
        }

        if (!StringUtils.isNullOrEmpty(this.applicationId) && !StringUtils.isNullOrEmpty(this.txServiceGroup)) {
            TMClient.init(this.applicationId, this.txServiceGroup); 
                     //初始化事务管理器transaction manager

            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Transaction Manager Client is initialized. applicationId[" + this.applicationId + "] txServiceGroup[" + this.txServiceGroup + "]");
            }

            RMClient.init(this.applicationId, this.txServiceGroup); 
                     //初始化资源管理器resource manager

            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Resource Manager is initialized. applicationId[" + this.applicationId + "] txServiceGroup[" + this.txServiceGroup + "]");
            }

            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Global Transaction Clients are initialized. ");
            }

            this.registerSpringShutdownHook(); //注册shutDownHook,关机前释放相关资源
        } else {
            throw new IllegalArgumentException("applicationId: " + this.applicationId + ", txServiceGroup: " + this.txServiceGroup);
        }
    }

    private void registerSpringShutdownHook() { 
        if (this.applicationContext instanceof ConfigurableApplicationContext) {
            ((ConfigurableApplicationContext)this.applicationContext).registerShutdownHook();
            ShutdownHook.removeRuntimeShutdownHook();
        }

        ShutdownHook.getInstance().addDisposable(TmRpcClient.getInstance(this.applicationId, this.txServiceGroup));
                                   //关机前释放事务管理器transaction manager
        ShutdownHook.getInstance().addDisposable(RmRpcClient.getInstance(this.applicationId, this.txServiceGroup));
                                   //关机前释放资源管理器resource manager
    }

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
                                    //创建代理对象

        if (this.disableGlobalTransaction) { 
            return bean;              //如果禁止全局事务,直接返回bean
        } else {
            try {
                synchronized(PROXYED_SET) {
                    if (PROXYED_SET.contains(beanName)) {
                        return bean;  //如果已经创建beanName的代理对象,直接返回bean
                    } else {
                        this.interceptor = null;
                        if (TCCBeanParserUtils.isTccAutoProxy(bean, beanName, this.applicationContext)) {
                            this.interceptor = new TccActionInterceptor(TCCBeanParserUtils.getRemotingDesc(beanName));
                                      //tcc模式,拦截器为TccActionInterceptor
                        } else {
                            Class serviceInterface = SpringProxyUtils.findTargetClass(bean);
                            Class[] interfacesIfJdk = SpringProxyUtils.findInterfaces(bean);
                            if (!this.existsAnnotation(new Class[]{serviceInterface}) && !this.existsAnnotation(interfacesIfJdk)) {
                                return bean;
                            }

                            if (this.interceptor == null) {
                                this.interceptor = new GlobalTransactionalInterceptor(this.failureHandlerHook);
                                     //at模式,拦截器为GlobalTransactionalInterceptor
                                ConfigurationFactory.getInstance().addConfigListener("service.disableGlobalTransaction", (ConfigurationChangeListener)this.interceptor);
                            }
                        }

                        LOGGER.info("Bean[" + bean.getClass().getName() + "] with name [" + beanName + "] would use interceptor [" + this.interceptor.getClass().getName() + "]");
                        if (!AopUtils.isAopProxy(bean)) {
                            bean = super.wrapIfNecessary(bean, beanName, cacheKey);
                        } else {
                            AdvisedSupport advised = SpringProxyUtils.getAdvisedSupport(bean);
                            Advisor[] advisor = this.buildAdvisors(beanName, this.getAdvicesAndAdvisorsForBean((Class)null, (String)null, (TargetSource)null));
                            Advisor[] var7 = advisor;
                            int var8 = advisor.length;

                            for(int var9 = 0; var9 < var8; ++var9) {
                                Advisor avr = var7[var9];
                                advised.addAdvisor(0, avr);
                            }
                        }

                        PROXYED_SET.add(beanName);
                        return bean;
                    }
                }
            } catch (Exception var13) {
                throw new RuntimeException(var13);
            }
        }
    }

    private boolean existsAnnotation(Class[] classes) {//判断是否含有注解
        if (classes != null && classes.length > 0) {
            Class[] var2 = classes;
            int var3 = classes.length;

            for(int var4 = 0; var4 < var3; ++var4) {
                Class clazz = var2[var4];
                if (clazz != null) {
                    Method[] methods = clazz.getMethods();
                    Method[] var7 = methods;
                    int var8 = methods.length;

                    for(int var9 = 0; var9 < var8; ++var9) {
                        Method method = var7[var9];
                        GlobalTransactional trxAnno = (GlobalTransactional)method.getAnnotation(GlobalTransactional.class);
                        if (trxAnno != null) {
                            return true;
                        }//如果方法上标注注解@GlobalTransactional,返回true

                        GlobalLock lockAnno = (GlobalLock)method.getAnnotation(GlobalLock.class);
                        if (lockAnno != null) {
                            return true;
                        }//如果方法上标注注解@GlobalLock,返回true
                    }
                }
            }
        }

        return false;
    }//方法上没有注解@GlobalTransactional、@GlobalLock,返回false

    private MethodDesc makeMethodDesc(GlobalTransactional anno, Method method) {
        return new MethodDesc(anno, method);
    }

    protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource customTargetSource) throws BeansException {
        return new Object[]{this.interceptor};
    }

    public void afterPropertiesSet() {
        if (this.disableGlobalTransaction) {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Global transaction is disabled.");
            }

        } else {
            this.initClient();
        }
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        this.setBeanFactory(applicationContext);
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        if (bean instanceof DataSourceProxy && ConfigurationFactory.getInstance().getBoolean("client.support.spring.datasource.autoproxy", false)) {
            throw new ShouldNeverHappenException("Auto proxy of DataSource can't be enabled as you've created a DataSourceProxy bean.Please consider removing DataSourceProxy bean or disabling auto proxy of DataSource.");
        } else {
            return super.postProcessBeforeInitialization(bean, beanName);
        }
    }

    public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
        if (bean instanceof DataSource && !(bean instanceof DataSourceProxy) && ConfigurationFactory.getInstance().getBoolean("client.support.spring.datasource.autoproxy", false)) {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Auto proxy of [{}]", beanName);
            }

            final DataSourceProxy dataSourceProxy = DataSourceProxyHolder.get().putDataSource((DataSource)bean);
            Class[] interfaces = SpringProxyUtils.getAllInterfaces(bean);
            return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvocationHandler() {
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Method m = BeanUtils.findDeclaredMethod(DataSourceProxy.class, method.getName(), method.getParameterTypes());
                    if (null != m) {
                        return m.invoke(dataSourceProxy, args);
                    } else {
                        boolean oldAccessible = method.isAccessible();

                        Object var6;
                        try {
                            method.setAccessible(true);
                            var6 = method.invoke(bean, args);
                        } finally {
                            method.setAccessible(oldAccessible);
                        }

                        return var6;
                    }
                }
            });
        } else {
            return super.postProcessAfterInitialization(bean, beanName);
        }
    }
}

 

TccActionInterceptor:tcc模式拦截器

public class TccActionInterceptor implements MethodInterceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(TccActionInterceptor.class);
    private ActionInterceptorHandler actionInterceptorHandler = new ActionInterceptorHandler();
    protected RemotingDesc remotingDesc;

    public TccActionInterceptor() {
    }

    public TccActionInterceptor(RemotingDesc remotingDesc) {
        this.remotingDesc = remotingDesc;
    }

    public Object invoke(MethodInvocation invocation) throws Throwable {
        if (!RootContext.inGlobalTransaction()) {
            return invocation.proceed();  //如果没有开启全局事务,不做处理继续执行
        } else {
            Method method = this.getActionInterfaceMethod(invocation);
                                          //获取原始方法
            TwoPhaseBusinessAction businessAction = (TwoPhaseBusinessAction)method.getAnnotation(TwoPhaseBusinessAction.class);
                                          //获取标注了注解TwoPhaseBusinessAction的两阶段操作
            if (businessAction != null) {
                String xid = RootContext.getXID();
                RootContext.unbind();
                RootContext.bindInterceptorType(xid, BranchType.TCC);

                Object var7;
                try {
                    Object[] methodArgs = invocation.getArguments();
                    ActionInterceptorHandler var10000 = this.actionInterceptorHandler;
                    invocation.getClass();
                    Map ret = var10000.proceed(method, methodArgs, xid, businessAction, invocation::proceed);
                                         //执行相关操作,actionInterceptorHandler的proceed()方法

                    var7 = ret.get("result");
                } finally {
                    RootContext.unbindInterceptorType();
                    RootContext.bind(xid);
                }

                return var7;
            } else {
                return invocation.proceed();
            }
        }
    }

    protected Method getActionInterfaceMethod(MethodInvocation invocation) {
    protected Class getProxyInterface(Object proxyBean) throws Exception {

 

GlobalTransactionalInterceptor:at模式拦截器

public class GlobalTransactionalInterceptor implements ConfigurationChangeListener, MethodInterceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalTransactionalInterceptor.class);
    private static final FailureHandler DEFAULT_FAIL_HANDLER = new DefaultFailureHandlerImpl();
    private final TransactionalTemplate transactionalTemplate = new TransactionalTemplate();
    private final GlobalLockTemplate globalLockTemplate = new GlobalLockTemplate();
    private final FailureHandler failureHandler;
    private volatile boolean disable;

    public GlobalTransactionalInterceptor(FailureHandler failureHandler) {
        this.failureHandler = failureHandler == null ? DEFAULT_FAIL_HANDLER : failureHandler;
        this.disable = ConfigurationFactory.getInstance().getBoolean("service.disableGlobalTransaction", false);
    }

    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        Class targetClass = methodInvocation.getThis() != null ? AopUtils.getTargetClass(methodInvocation.getThis()) : null;
        Method specificMethod = ClassUtils.getMostSpecificMethod(methodInvocation.getMethod(), targetClass);
        Method method = BridgeMethodResolver.findBridgedMethod(specificMethod);
        GlobalTransactional globalTransactionalAnnotation = (GlobalTransactional)this.getAnnotation(method, GlobalTransactional.class);
        GlobalLock globalLockAnnotation = (GlobalLock)this.getAnnotation(method, GlobalLock.class);
        if (!this.disable && globalTransactionalAnnotation != null) {
            return this.handleGlobalTransaction(methodInvocation, globalTransactionalAnnotation);
                                   //处理@GlobalTransactional标注的方法
        } else {
            return !this.disable && globalLockAnnotation != null ? this.handleGlobalLock(methodInvocation) : methodInvocation.proceed();
                                   //处理@GlobalLock标注的方法
        }
    }

    private Object handleGlobalLock(MethodInvocation methodInvocation) throws Exception {
                                   //处理全局锁

        return this.globalLockTemplate.execute(() -> {
            try {
                return methodInvocation.proceed();
            } catch (Exception var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new RuntimeException(var3);
            }
        });
    }

    private Object handleGlobalTransaction(final MethodInvocation methodInvocation, final GlobalTransactional globalTrxAnno) throws Throwable {
                                   //处理全局事务

        try {
            return this.transactionalTemplate.execute(new TransactionalExecutor() {
                public Object execute() throws Throwable {
                    return methodInvocation.proceed();
                }

                public String name() {
                    String name = globalTrxAnno.name();
                    return !StringUtils.isNullOrEmpty(name) ? name : GlobalTransactionalInterceptor.this.formatMethod(methodInvocation.getMethod());
                }

                public TransactionInfo getTransactionInfo() {
                    TransactionInfo transactionInfo = new TransactionInfo();
                    transactionInfo.setTimeOut(globalTrxAnno.timeoutMills());
                    transactionInfo.setName(this.name());
                    Set rollbackRules = new LinkedHashSet();
                    Class[] var3 = globalTrxAnno.rollbackFor();
                    int var4 = var3.length;

                    int var5;
                    Class rbRule;
                    for(var5 = 0; var5 < var4; ++var5) {
                        rbRule = var3[var5];
                        rollbackRules.add(new RollbackRule(rbRule));
                    }

                    String[] var7 = globalTrxAnno.rollbackForClassName();
                    var4 = var7.length;

                    String rbRulex;
                    for(var5 = 0; var5 < var4; ++var5) {
                        rbRulex = var7[var5];
                        rollbackRules.add(new RollbackRule(rbRulex));
                    }

                    var3 = globalTrxAnno.noRollbackFor();
                    var4 = var3.length;

                    for(var5 = 0; var5 < var4; ++var5) {
                        rbRule = var3[var5];
                        rollbackRules.add(new NoRollbackRule(rbRule));
                    }

                    var7 = globalTrxAnno.noRollbackForClassName();
                    var4 = var7.length;

                    for(var5 = 0; var5 < var4; ++var5) {
                        rbRulex = var7[var5];
                        rollbackRules.add(new NoRollbackRule(rbRulex));
                    }

                    transactionInfo.setRollbackRules(rollbackRules);
                    return transactionInfo;
                }
            });
        } catch (ExecutionException var5) {
            Code code = var5.getCode();
            switch(code) {
            case RollbackDone:
                throw var5.getOriginalException();
            case BeginFailure:
                this.failureHandler.onBeginFailure(var5.getTransaction(), var5.getCause());
                throw var5.getCause();
            case CommitFailure:
                this.failureHandler.onCommitFailure(var5.getTransaction(), var5.getCause());
                throw var5.getCause();
            case RollbackFailure:
                this.failureHandler.onRollbackFailure(var5.getTransaction(), var5.getCause());
                throw var5.getCause();
            default:
                throw new ShouldNeverHappenException(String.format("Unknown TransactionalExecutor.Code: %s", code));
            }
        }
    }

    private  T getAnnotation(Method method, Class clazz) {
    private String formatMethod(Method method) {

    public void onChangeEvent(ConfigurationChangeEvent event) { 
  

 

 

*****************************

相关注解

 

TwoPhaseBusinessAction:tcc模式两阶段操作注解

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})                   //注解标注在方法上
@Inherited
public @interface TwoPhaseBusinessAction {
    String name();

    String commitMethod() default "commit";     //提交方法

    String rollbackMethod() default "rollback"; //回滚方法
}

 

GlobalLock:全局锁

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})          //标注在方法上
@Inherited
public @interface GlobalLock {
}

 

GlobalTransactional:全局事务

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})         //标注在方法上
@Inherited
public @interface GlobalTransactional {
    int timeoutMills() default 60000;

    String name() default "";

    Class[] rollbackFor() default {};     //抛出指定异常回滚
    String[] rollbackForClassName() default {};

    Class[] noRollbackFor() default {};   //抛出指定异常不回滚
    String[] noRollbackForClassName() default {};
}

 

 

*****************************

数据源自动代理 

 

EnableAutoDataSourceProxy:自动创建代理数据源,该注解seata-spring-boot-starter 1.1.0开始使用

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({AutoDataSourceProxyRegistrar.class})
@Documented
public @interface EnableAutoDataSourceProxy {
    boolean useJdkProxy() default false;
}

 

AutoDataSourceProxyRegistrar:自动数据源代理注册类

public class AutoDataSourceProxyRegistrar implements ImportBeanDefinitionRegistrar {
    private static final String ATTRIBUTE_KEY_USE_JDK_PROXY = "useJdkProxy";
    public static final String BEAN_NAME_SEATA_DATA_SOURCE_BEAN_POST_PROCESSOR = "seataDataSourceBeanPostProcessor";

    public AutoDataSourceProxyRegistrar() {
    }

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        if (!registry.containsBeanDefinition("seataDataSourceBeanPostProcessor")) {
            boolean useJdkProxy = Boolean.valueOf(importingClassMetadata.getAnnotationAttributes(EnableAutoDataSourceProxy.class.getName()).get("useJdkProxy").toString());
            AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SeataDataSourceBeanPostProcessor.class).addConstructorArgValue(useJdkProxy).getBeanDefinition();
            registry.registerBeanDefinition("seataDataSourceBeanPostProcessor", beanDefinition);
        }

    }
}

 

SeataDataSourceBeanPostProcessor:创建代理数据源操作类

public class SeataDataSourceBeanPostProcessor implements BeanPostProcessor {
    private static final Logger LOGGER = LoggerFactory.getLogger(SeataDataSourceBeanPostProcessor.class);
    private final boolean useJdkProxy;     //是否使用jdk代理

    public SeataDataSourceBeanPostProcessor(boolean useJdkProxy) {
        this.useJdkProxy = useJdkProxy;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof DataSource && !(bean instanceof DataSourceProxy)) {
                                           //bean是DataSource实例,且不是数据源代理类,则创建代理数据源
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Auto proxy of [{}]", beanName);
            }

            return this.proxyDataSource(bean);
        } else {
            return bean;  //否则直接返回bean
        }
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        if (bean instanceof DataSourceProxy) {
                  //自动创建数据源不能和手工创建数据源同时配置,否则报错
            throw new ShouldNeverHappenException("Auto proxy of DataSource can't be enabled as you've created a DataSourceProxy bean.Please consider removing DataSourceProxy bean or disabling auto proxy of DataSource.");
        } else {
            return bean;
        }
    }

    private Object proxyDataSource(Object originBean) {   //创建代理数据源
    private Object handleMethodProxy(DataSourceProxy dataSourceProxy, Method method, Object[] args, Object originBean) throws InvocationTargetException, IllegalAccessException {
                   //创建代理数据源的具体操作

 

 

*****************************

事务管理器

 

TransactionManager:事务管理器接口

public interface TransactionManager {
 
    String begin(String var1, String var2, String var3, int var4) throws TransactionException;  //开启全局事务
    GlobalStatus commit(String var1) throws TransactionException;  //提交全局事务
    GlobalStatus rollback(String var1) throws TransactionException;//回滚全局事务

    GlobalStatus getStatus(String var1) throws TransactionException; //获取全局事务执行状态
    GlobalStatus globalReport(String var1, GlobalStatus var2) throws TransactionException;
                                                                     //提交全局事务执行状态
}

 

DefaultTransactionManager:全局事务管理器默认实现类

public class DefaultTransactionManager implements TransactionManager {
    public DefaultTransactionManager() {
    }

    public String begin(String applicationId, String transactionServiceGroup, String name, int timeout) throws TransactionException {
                       //开启全局事务
        GlobalBeginRequest request = new GlobalBeginRequest();
        request.setTransactionName(name);
        request.setTimeout(timeout);
        GlobalBeginResponse response = (GlobalBeginResponse)this.syncCall(request);
        if (response.getResultCode() == ResultCode.Failed) {
            throw new TmTransactionException(TransactionExceptionCode.BeginFailed, response.getMsg());
        } else {
            return response.getXid();
        }
    }

    public GlobalStatus commit(String xid) throws TransactionException {
                        //提交全局事务
        GlobalCommitRequest globalCommit = new GlobalCommitRequest();
        globalCommit.setXid(xid);
        GlobalCommitResponse response = (GlobalCommitResponse)this.syncCall(globalCommit);
        return response.getGlobalStatus();
    }

    public GlobalStatus rollback(String xid) throws TransactionException {
                        //回滚全局事务
        GlobalRollbackRequest globalRollback = new GlobalRollbackRequest();
        globalRollback.setXid(xid);
        GlobalRollbackResponse response = (GlobalRollbackResponse)this.syncCall(globalRollback);
        return response.getGlobalStatus();
    }

    public GlobalStatus getStatus(String xid) throws TransactionException {
                        //获取全局事务执行状态
        GlobalStatusRequest queryGlobalStatus = new GlobalStatusRequest();
        queryGlobalStatus.setXid(xid);
        GlobalStatusResponse response = (GlobalStatusResponse)this.syncCall(queryGlobalStatus);
        return response.getGlobalStatus();
    }

    public GlobalStatus globalReport(String xid, GlobalStatus globalStatus) throws TransactionException {
                        //提交全局事务执行状态
        GlobalReportRequest globalReport = new GlobalReportRequest();
        globalReport.setXid(xid);
        globalReport.setGlobalStatus(globalStatus);
        GlobalReportResponse response = (GlobalReportResponse)this.syncCall(globalReport);
        return response.getGlobalStatus();
    }

    private AbstractTransactionResponse syncCall(AbstractTransactionRequest request) throws TransactionException {
        try {
            return (AbstractTransactionResponse)TmRpcClient.getInstance().sendMsgWithResponse(request);
                                                       //执行相关事务请求
        } catch (TimeoutException var3) {
            throw new TmTransactionException(TransactionExceptionCode.IO, "RPC timeout", var3);
        }
    }
}

 

 

*****************************

资源管理器

 

ResourceManager:资源管理器接口

public interface ResourceManager extends ResourceManagerInbound, ResourceManagerOutbound {

    void registerResource(Resource var1);   //注册资源服务器
    void unregisterResource(Resource var1); //断开资源服务器

    Map getManagedResources();

    BranchType getBranchType();   //获取事务模式:at、tcc、saga
}

 

BranchType:事务模式

public enum BranchType {
    AT,
    TCC,
    SAGA;

    private BranchType() {
    }

    public static BranchType get(byte ordinal) {
    public static BranchType get(int ordinal) {

 

ResourceManagerInBound:提交、回滚本地事务接口

public interface ResourceManagerInbound {

    BranchStatus branchCommit(BranchType var1, String var2, long var3, String var5, String var6) throws TransactionException;
                              //提交分支事务

    BranchStatus branchRollback(BranchType var1, String var2, long var3, String var5, String var6) throws TransactionException;
                              //回滚分支事务
}

 

ResourcemanagerOutBound:注册、回报之行状态、本地资源锁定接口

public interface ResourceManagerOutbound {
 
   Long branchRegister(BranchType var1, String var2, String var3, String var4, String var5, String var6) throws TransactionException;
                      //注册本地事务

    void branchReport(BranchType var1, String var2, long var3, BranchStatus var5, String var6) throws TransactionException;
                      //汇报本地事务状态

    boolean lockQuery(BranchType var1, String var2, String var3, String var4) throws TransactionException;
                      //锁定本地相关资源
}

 

AbstractResourceManager

public abstract class AbstractResourceManager implements ResourceManager {
    protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractResourceManager.class);

    public AbstractResourceManager() {
    }

    public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid, String applicationData, String lockKeys) throws TransactionException {

    public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status, String applicationData) throws TransactionException {

    public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys) throws TransactionException {
        return false;
    }

    public void unregisterResource(Resource resource) {
        throw new NotSupportYetException("unregister a resource");
    }

    public void registerResource(Resource resource) {
        RmRpcClient.getInstance().registerResource(resource.getResourceGroupId(), resource.getResourceId());
    }
}

 

**********************

at 模式资源管理器

 

DataSourceManager

public class DataSourceManager extends AbstractResourceManager implements Initialize {
    private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceManager.class);
    private ResourceManagerInbound asyncWorker;
    private Map dataSourceCache = new ConcurrentHashMap();

    public void setAsyncWorker(ResourceManagerInbound asyncWorker) {
        this.asyncWorker = asyncWorker;
    }

    public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys) throws TransactionException {
        try {
            GlobalLockQueryRequest request = new GlobalLockQueryRequest();
            request.setXid(xid);
            request.setLockKey(lockKeys);
            request.setResourceId(resourceId);
            GlobalLockQueryResponse response = null;
            if (RootContext.inGlobalTransaction()) {
                response = (GlobalLockQueryResponse)RmRpcClient.getInstance().sendMsgWithResponse(request);
            } else {
                if (!RootContext.requireGlobalLock()) {
                    throw new RuntimeException("unknow situation!");
                }

                response = (GlobalLockQueryResponse)RmRpcClient.getInstance().sendMsgWithResponse(this.loadBalance(), request, (long)NettyClientConfig.getRpcRequestTimeout());
            }

            if (response.getResultCode() == ResultCode.Failed) {
                throw new TransactionException(response.getTransactionExceptionCode(), "Response[" + response.getMsg() + "]");
            } else {
                return response.isLockable();
            }
        } catch (TimeoutException var7) {
            throw new RmTransactionException(TransactionExceptionCode.IO, "RPC Timeout", var7);
        } catch (RuntimeException var8) {
            throw new RmTransactionException(TransactionExceptionCode.LockableCheckFailed, "Runtime", var8);
        }
    }

    private String loadBalance() {
        InetSocketAddress address = null;

        try {
            List inetSocketAddressList = RegistryFactory.getInstance().lookup(TmRpcClient.getInstance().getTransactionServiceGroup());
            address = (InetSocketAddress)LoadBalanceFactory.getInstance().select(inetSocketAddressList);
        } catch (Exception var3) {
            LOGGER.error(var3.getMessage());
        }

        if (address == null) {
            throw new FrameworkException(FrameworkErrorCode.NoAvailableService);
        } else {
            return NetUtil.toStringAddress(address);
        }
    }

    public synchronized void initAsyncWorker(ResourceManagerInbound asyncWorker) {
        this.setAsyncWorker(asyncWorker);
    }

    public DataSourceManager() {
    }

    public void init() {
        AsyncWorker asyncWorker = new AsyncWorker();
        asyncWorker.init();
        this.initAsyncWorker(asyncWorker);
    }

    public void registerResource(Resource resource) {
        DataSourceProxy dataSourceProxy = (DataSourceProxy)resource;  //注册代理数据源
        this.dataSourceCache.put(dataSourceProxy.getResourceId(), dataSourceProxy);
        super.registerResource(dataSourceProxy);
    }

    public void unregisterResource(Resource resource) {
        throw new NotSupportYetException("unregister a resource");
    }

    public DataSourceProxy get(String resourceId) {
        return (DataSourceProxy)this.dataSourceCache.get(resourceId);
    }

    public BranchStatus branchCommit(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException {
        return this.asyncWorker.branchCommit(branchType, xid, branchId, resourceId, applicationData);
    }

    public BranchStatus branchRollback(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException {
        DataSourceProxy dataSourceProxy = this.get(resourceId);
        if (dataSourceProxy == null) {
            throw new ShouldNeverHappenException();
        } else {
            try {
                UndoLogManagerFactory.getUndoLogManager(dataSourceProxy.getDbType()).undo(dataSourceProxy, xid, branchId);
            } catch (TransactionException var9) {
                StackTraceLogger.info(LOGGER, var9, "[stacktrace]branchRollback failed. branchType:[{}], xid:[{}], branchId:[{}], resourceId:[{}], applicationData:[{}]. stacktrace:[{}]", new Object[]{branchType, xid, branchId, resourceId, applicationData, var9.getMessage()}, "branchRollback failed reason [{}]", new Object[]{var9.getMessage()});
                if (var9.getCode() == TransactionExceptionCode.BranchRollbackFailed_Unretriable) {
                    return BranchStatus.PhaseTwo_RollbackFailed_Unretryable;
                }

                return BranchStatus.PhaseTwo_RollbackFailed_Retryable;
            }

            return BranchStatus.PhaseTwo_Rollbacked;
        }
    }

    public Map getManagedResources() {
        return this.dataSourceCache;
    }

    public BranchType getBranchType() {
        return BranchType.AT;
    }
}

 

DataSourceProxy:数据源代理

public class DataSourceProxy extends AbstractDataSourceProxy implements Resource {
    private String resourceGroupId;
    private static final String DEFAULT_RESOURCE_GROUP_ID = "DEFAULT";
    private String jdbcUrl;
    private String dbType;
    private static boolean ENABLE_TABLE_META_CHECKER_ENABLE = ConfigurationFactory.getInstance().getBoolean("client.rm.tableMetaCheckEnable", false);
    private static final long TABLE_META_CHECKER_INTERVAL = 60000L;
    private final ScheduledExecutorService tableMetaExcutor;

    public DataSourceProxy(DataSource targetDataSource) {
        this(targetDataSource, "DEFAULT");
    }

    public DataSourceProxy(DataSource targetDataSource, String resourceGroupId) {
        super(targetDataSource);
        this.tableMetaExcutor = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("tableMetaChecker", 1, true));
        this.init(targetDataSource, resourceGroupId);
    }

    private void init(DataSource dataSource, String resourceGroupId) {  //相关初始化操作

    public Connection getPlainConnection() throws SQLException {

    public String getDbType() {
        return this.dbType;
    }

    public ConnectionProxy getConnection() throws SQLException { //获取代理连接
        Connection targetConnection = this.targetDataSource.getConnection();
        return new ConnectionProxy(this, targetConnection);
    }

    public ConnectionProxy getConnection(String username, String password) throws SQLException {
                                                                //使用用户名、密码获取代理连接
        Connection targetConnection = this.targetDataSource.getConnection(username, password);
        return new ConnectionProxy(this, targetConnection);
    }


    public String getResourceGroupId() {
    public String getResourceId() {

    public BranchType getBranchType() {
        return BranchType.AT;
    }
}

 

ConnectionProxy:连接代理

public class ConnectionProxy extends AbstractConnectionProxy {
    private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionProxy.class);
    private ConnectionContext context = new ConnectionContext();
    private static final int REPORT_RETRY_COUNT = ConfigurationFactory.getInstance().getInt("client.rm.reportRetryCount", 5);
    public static final boolean IS_REPORT_SUCCESS_ENABLE = ConfigurationFactory.getInstance().getBoolean("client.rm.reportSuccessEnable", false);
    private static final ConnectionProxy.LockRetryPolicy LOCK_RETRY_POLICY = new ConnectionProxy.LockRetryPolicy();

    public ConnectionProxy(DataSourceProxy dataSourceProxy, Connection targetConnection) {

****************
普通方法

    public ConnectionContext getContext() {
    public void bind(String xid) {

    public void setGlobalLockRequire(boolean isLock) {    //全局锁相关操作
    public boolean isGlobalLockRequire() {
    public void checkLock(String lockKeys) throws SQLException {
    public boolean lockQuery(String lockKeys) throws SQLException {

    private void recognizeLockKeyConflictException(TransactionException te) throws SQLException {
    private void recognizeLockKeyConflictException(TransactionException te, String lockKeys) throws SQLException {

    public void appendUndoLog(SQLUndoLog sqlUndoLog) {    //undo日志
    public void appendLockKey(String lockKey) {           //全局锁

    public void commit() throws SQLException {
    private void doCommit() throws SQLException {
    private void processLocalCommitWithGlobalLocks() throws SQLException {
    private void processGlobalTransactionCommit() throws SQLException {

    private void register() throws TransactionException {
    public void rollback() throws SQLException {
    public void setAutoCommit(boolean autoCommit) throws SQLException {
    private void report(boolean commitDone) throws SQLException {

 

AbstarctConnectionProxy

public abstract class AbstractConnectionProxy implements Connection {
    protected DataSourceProxy dataSourceProxy;
    protected Connection targetConnection;

    public AbstractConnectionProxy(DataSourceProxy dataSourceProxy, Connection targetConnection) {

**************
部分方法

    public Statement createStatement() throws SQLException {
        Statement targetStatement = this.getTargetConnection().createStatement();
        return new StatementProxy(this, targetStatement);
    }//创建statement代理

    public PreparedStatement prepareStatement(String sql) throws SQLException {
        String dbType = this.getDbType();
        PreparedStatement targetPreparedStatement = null;
        if (RootContext.inGlobalTransaction()) {
            SQLRecognizer sqlRecognizer = SQLVisitorFactory.get(sql, dbType);
            if (sqlRecognizer != null && sqlRecognizer.getSQLType() == SQLType.INSERT) {
                String tableName = ColumnUtils.delEscape(sqlRecognizer.getTableName(), dbType);
                TableMeta tableMeta = TableMetaCacheFactory.getTableMetaCache(dbType).getTableMeta(this.getTargetConnection(), tableName, this.getDataSourceProxy().getResourceId());
                targetPreparedStatement = this.getTargetConnection().prepareStatement(sql, new String[]{tableMeta.getPkName()});
            }
        }

        if (targetPreparedStatement == null) {
            targetPreparedStatement = this.getTargetConnection().prepareStatement(sql);
        }

        return new PreparedStatementProxy(this, targetPreparedStatement, sql);
    }//创建preparedStatementProxy代理

 

StatementProxy:使用ExecuteTemplate执行sql语句

public class StatementProxy extends AbstractStatementProxy {
    public StatementProxy(AbstractConnectionProxy connectionWrapper, T targetStatement, String targetSQL) throws SQLException {
        super(connectionWrapper, targetStatement, targetSQL);
    }

    public StatementProxy(AbstractConnectionProxy connectionWrapper, T targetStatement) throws SQLException {
        this(connectionWrapper, targetStatement, (String)null);
    }

    public ConnectionProxy getConnectionProxy() {
        return (ConnectionProxy)super.getConnectionProxy();
    }

    public ResultSet executeQuery(String sql) throws SQLException {
        this.targetSQL = sql;
        return (ResultSet)ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.executeQuery((String)args[0]);
        }, new Object[]{sql});
    }

    public int executeUpdate(String sql) throws SQLException {
        this.targetSQL = sql;
        return (Integer)ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.executeUpdate((String)args[0]);
        }, new Object[]{sql});
    }

    public boolean execute(String sql) throws SQLException {
        this.targetSQL = sql;
        return (Boolean)ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.execute((String)args[0]);
        }, new Object[]{sql});
    }

    public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
        this.targetSQL = sql;
        return (Integer)ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.executeUpdate((String)args[0], (Integer)args[1]);
        }, new Object[]{sql, autoGeneratedKeys});
    }

    public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
        this.targetSQL = sql;
        return (Integer)ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.executeUpdate((String)args[0], (int[])((int[])args[1]));
        }, new Object[]{sql, columnIndexes});
    }

    public int executeUpdate(String sql, String[] columnNames) throws SQLException {
        this.targetSQL = sql;
        return (Integer)ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.executeUpdate((String)args[0], (String[])((String[])args[1]));
        }, new Object[]{sql, columnNames});
    }

    public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
        this.targetSQL = sql;
        return (Boolean)ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.execute((String)args[0], (Integer)args[1]);
        }, new Object[]{sql, autoGeneratedKeys});
    }

    public boolean execute(String sql, int[] columnIndexes) throws SQLException {
        this.targetSQL = sql;
        return (Boolean)ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.execute((String)args[0], (int[])((int[])args[1]));
        }, new Object[]{sql, columnIndexes});
    }

    public boolean execute(String sql, String[] columnNames) throws SQLException {
        this.targetSQL = sql;
        return (Boolean)ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.execute((String)args[0], (String[])((String[])args[1]));
        }, new Object[]{sql, columnNames});
    }

    public int[] executeBatch() throws SQLException {
        return (int[])ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.executeBatch();
        }, new Object[0]);
    }
}

 

PreparedStatementProxy:预编译语句代理,使用ExecuteTemplate执行sql语句

public class PreparedStatementProxy extends AbstractPreparedStatementProxy implements PreparedStatement, ParametersHolder {
    public ArrayList[] getParameters() {
        return this.parameters;
    }

    public PreparedStatementProxy(AbstractConnectionProxy connectionProxy, PreparedStatement targetStatement, String targetSQL) throws SQLException {
        super(connectionProxy, targetStatement, targetSQL);
    }

    public boolean execute() throws SQLException {
        return (Boolean)ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.execute();
        }, new Object[0]);
    }

    public ResultSet executeQuery() throws SQLException {
        return (ResultSet)ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.executeQuery();
        }, new Object[0]);
    }

    public int executeUpdate() throws SQLException {
        return (Integer)ExecuteTemplate.execute(this, (statement, args) -> {
            return statement.executeUpdate();
        }, new Object[0]);
    }
}
 
  

 

ExecuteTemplate:执行sql语句,并做事务处理

public class ExecuteTemplate {
    public ExecuteTemplate() {
    }

    public static  T execute(StatementProxy statementProxy, StatementCallback statementCallback, Object... args) throws SQLException {
        return execute((SQLRecognizer)null, statementProxy, statementCallback, args);
    }

    public static  T execute(SQLRecognizer sqlRecognizer, StatementProxy statementProxy, StatementCallback statementCallback, Object... args) throws SQLException {
        if (!RootContext.inGlobalTransaction() && !RootContext.requireGlobalLock()) {
            return statementCallback.execute(statementProxy.getTargetStatement(), args);
        } else {
            if (sqlRecognizer == null) {
                sqlRecognizer = SQLVisitorFactory.get(statementProxy.getTargetSQL(), statementProxy.getConnectionProxy().getDbType());
            }

            Object executor;
            if (sqlRecognizer == null) {
                executor = new PlainExecutor(statementProxy, statementCallback);
            } else {
                switch(sqlRecognizer.getSQLType()) {
                case INSERT:
                    executor = new InsertExecutor(statementProxy, statementCallback, sqlRecognizer);
                    break;
                case UPDATE:
                    executor = new UpdateExecutor(statementProxy, statementCallback, sqlRecognizer);
                    break;
                case DELETE:
                    executor = new DeleteExecutor(statementProxy, statementCallback, sqlRecognizer);
                    break;
                case SELECT_FOR_UPDATE:
                    executor = new SelectForUpdateExecutor(statementProxy, statementCallback, sqlRecognizer);
                    break;
                default:
                    executor = new PlainExecutor(statementProxy, statementCallback);
                }
            }

            try {
                T rs = ((Executor)executor).execute(args);
                return rs;
            } catch (Throwable var7) {
                Throwable ex = var7;
                if (!(var7 instanceof SQLException)) {
                    ex = new SQLException(var7);
                }

                throw (SQLException)ex;
            }
        }
    }
}

 

**********************

tcc 模式资源管理器

 

TccResourceManager

public class TCCResourceManager extends AbstractResourceManager {
    private Map tccResourceCache = new ConcurrentHashMap();

    public TCCResourceManager() {
    }

    public void registerResource(Resource resource) {
        TCCResource tccResource = (TCCResource)resource;
        this.tccResourceCache.put(tccResource.getResourceId(), tccResource);
        super.registerResource(tccResource);
    }

    public Map getManagedResources() {
        return this.tccResourceCache;
    }

    public BranchStatus branchCommit(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException {
        TCCResource tccResource = (TCCResource)this.tccResourceCache.get(resourceId);
        if (tccResource == null) {   //没有tccResource,直接抛出异常
            throw new ShouldNeverHappenException(String.format("TCC resource is not exist, resourceId: %s", resourceId));
        } else {
            Object targetTCCBean = tccResource.getTargetBean();  //获取目标对象
            Method commitMethod = tccResource.getCommitMethod(); //获取对应的commit方法
            if (targetTCCBean != null && commitMethod != null) {
                try {
                    boolean result = false;
                    BusinessActionContext businessActionContext = this.getBusinessActionContext(xid, branchId, resourceId, applicationData);
                    Object ret = commitMethod.invoke(targetTCCBean, businessActionContext);        //执行commit方法
                    LOGGER.info("TCC resource commit result : {}, xid: {}, branchId: {}, resourceId: {}", new Object[]{ret, xid, branchId, resourceId});
                    if (ret != null) {
                        if (ret instanceof TwoPhaseResult) {
                            result = ((TwoPhaseResult)ret).isSuccess();
                        } else {
                            result = (Boolean)ret;
                        }
                    }

                    return result ? BranchStatus.PhaseTwo_Committed : BranchStatus.PhaseTwo_CommitFailed_Retryable; //根据执行结果返回二阶段提交或者二阶段回滚
                } catch (Throwable var13) {
                    String msg = String.format("commit TCC resource error, resourceId: %s, xid: %s.", resourceId, xid);
                    LOGGER.error(msg, var13);
                    throw new FrameworkException(var13, msg);
                }
            } else {
                throw new ShouldNeverHappenException(String.format("TCC resource is not available, resourceId: %s", resourceId));
            }
        }
    }

    public BranchStatus branchRollback(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException {
        TCCResource tccResource = (TCCResource)this.tccResourceCache.get(resourceId);
        if (tccResource == null) {  //没有tcc资源则抛出异常
            throw new ShouldNeverHappenException(String.format("TCC resource is not exist, resourceId: %s", resourceId));
        } else {
            Object targetTCCBean = tccResource.getTargetBean();     //获取目标对象
            Method rollbackMethod = tccResource.getRollbackMethod();//获取回滚方法
            if (targetTCCBean != null && rollbackMethod != null) {
                try {
                    boolean result = false;
                    BusinessActionContext businessActionContext = this.getBusinessActionContext(xid, branchId, resourceId, applicationData);
                    Object ret = rollbackMethod.invoke(targetTCCBean, businessActionContext);  //执行回滚方法
                    LOGGER.info("TCC resource rollback result : {}, xid: {}, branchId: {}, resourceId: {}", new Object[]{ret, xid, branchId, resourceId});
                    if (ret != null) {
                        if (ret instanceof TwoPhaseResult) {
                            result = ((TwoPhaseResult)ret).isSuccess();
                        } else {
                            result = (Boolean)ret;
                        }
                    }

                    return result ? BranchStatus.PhaseTwo_Rollbacked : BranchStatus.PhaseTwo_RollbackFailed_Retryable;  //根据执行结果返回已回滚、或者回滚失败进行重试
                } catch (Throwable var13) {
                    String msg = String.format("rollback TCC resource error, resourceId: %s, xid: %s.", resourceId, xid);
                    LOGGER.error(msg, var13);
                    throw new FrameworkException(var13, msg);
                }
            } else {
                throw new ShouldNeverHappenException(String.format("TCC resource is not available, resourceId: %s", resourceId));
            }
        }
    }

    protected BusinessActionContext getBusinessActionContext(String xid, long branchId, String resourceId, String applicationData) {
        Map tccContext = StringUtils.isBlank(applicationData) ? new HashMap() : (Map)JSON.parse(applicationData);
        Map actionContextMap = (Map)((Map)tccContext).get("actionContext");
        BusinessActionContext businessActionContext = new BusinessActionContext(xid, String.valueOf(branchId), actionContextMap);
        businessActionContext.setActionName(resourceId);
        return businessActionContext;
    }

    public BranchType getBranchType() {
        return BranchType.TCC;
    }
}

 

 

你可能感兴趣的:(spring,cloud,事务)