从源码分析seata如何使用

本文从源码层面分析Seata如何在Spring Cloud环境中使用。首先介绍引入Seata的相关依赖版本,接着探讨`application.properties`中的配置项。文章详细讲解了Seata的`GlobalTransactionScanner`和`SeataAutoDataSourceProxyCreator`类的角色,以及它们如何创建代理并处理事务。文中还阐述了`GlobalTransactionalInterceptor`的工作机制,强调其如何通知TC开始和结束事务。最后,分析了Seata如何生成和使用undo log,以及在本地事务提交过程中如何处理锁和重试机制。
摘要由CSDN通过智能技术生成

使用方式

引入jar包

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <revision>2.2.1.RELEASE</revision>
        </dependency>

对应的版本:
spring cloud:2.2.2.RELEASE
spring boot:2.2.5.RELEASE
需要使用其他版本参考spring boot 1.5如何最简单的使用seata最新版

application.properties

seata.enabled=true
spring.cloud.alibaba.seata.tx-service-group=account-service
seata.service.vgroup-mapping.account-service=default
seata.service.grouplist.default=127.0.0.1:8091
seata.service.disable-global-transaction=false

seata.enabled表示是否开启spring starter的自动注册,SeataAutoConfiguration类通过判断是否有这个属性来决定是否使配置自动生效,spring里面是通过这个注解来实现的@ConditionalOnProperty(prefix = StarterConstants.SEATA_PREFIX, name = “enabled”, havingValue = “true”, matchIfMissing = true)

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

    @Bean(BEAN_NAME_SPRING_APPLICATION_CONTEXT_PROVIDER)
    @ConditionalOnMissingBean(name = {
   BEAN_NAME_SPRING_APPLICATION_CONTEXT_PROVIDER})
    public SpringApplicationContextProvider springApplicationContextProvider() {
   
        return new SpringApplicationContextProvider();
    }

    @Bean(BEAN_NAME_FAILURE_HANDLER)
    @ConditionalOnMissingBean(FailureHandler.class)
    public FailureHandler failureHandler() {
   
        return new DefaultFailureHandlerImpl();
    }

    @Bean
    @DependsOn({
   BEAN_NAME_SPRING_APPLICATION_CONTEXT_PROVIDER, BEAN_NAME_FAILURE_HANDLER})
    @ConditionalOnMissingBean(GlobalTransactionScanner.class)
    public GlobalTransactionScanner globalTransactionScanner(SeataProperties seataProperties, FailureHandler failureHandler) {
   
        if (LOGGER.isInfoEnabled()) {
   
            LOGGER.info("Automatically configure Seata");
        }
        return new GlobalTransactionScanner(seataProperties.getApplicationId(), seataProperties.getTxServiceGroup(), failureHandler);
    }

    @Bean(BEAN_NAME_SEATA_AUTO_DATA_SOURCE_PROXY_CREATOR)
    @ConditionalOnProperty(prefix = StarterConstants.SEATA_PREFIX, name = {
   "enableAutoDataSourceProxy", "enable-auto-data-source-proxy"}, havingValue = "true", matchIfMissing = true)
    @ConditionalOnMissingBean(SeataAutoDataSourceProxyCreator.class)
    public SeataAutoDataSourceProxyCreator seataAutoDataSourceProxyCreator(SeataProperties seataProperties) {
   
        return new SeataAutoDataSourceProxyCreator(seataProperties.isUseJdkProxy(),seataProperties.getExcludesForAutoProxying());
    }
}

SeataAutoConfiguration里面初始化了一个GlobalTransactionScanner和SeataAutoDataSourceProxyCreator,这两个类一个是用来给标记了GlobalTransactional和GlobalLock注解的方法创建代理类,并设置相应的切面,另一个是给datasource创建代理,最终通过类DatasourceProxy来实现本地事务的提交。下面来分析GlobalTransactionScanner

public class GlobalTransactionScanner extends AbstractAutoProxyCreator
    implements InitializingBean, ApplicationContextAware,
    DisposableBean {
   
    
    private void initClient() {
   
        //负责全局事务 会与通信
        TMClient.init(applicationId, txServiceGroup);
       //负责分支事务 会与通信
        RMClient.init(applicationId, txServiceGroup);
        registerSpringShutdownHook();
    }

    @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) {
   
                        if (globalTransactionalInterceptor == null) {
   
                            globalTransactionalInterceptor = new GlobalTransactionalInterceptor(failureHandlerHook);
                            ConfigurationCache.addConfigListener(
                                ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION,
                                (ConfigurationChangeListener)globalTransactionalInterceptor);
                        }
                        interceptor = globalTransactionalInterceptor;
                    }
                }

                LOGGER.info("Bean[{}] with name [{}] would use interceptor [{}]", bean.getClass().getName(), beanName, interceptor.getClass().getName());
                if (!AopUtils.isAopProxy(bean)) {
   
                    bean = super.wrapIfNecessary(bean, beanName, cacheKey);
                } else {
   
                    AdvisedSupport advised = SpringProxyUtils.getAdvisedSupport(bean);
                    Advisor[] advisor = 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值