spring-boot - Spring 云任务的 SimpleTaskConfiguration 和 Spring Batch 的 SimpleBatchConfiguration 防止 XA 事务的 Spring Boot 自动配置

标签 spring-boot spring-batch distributed-transactions spring-cloud-task

我正在尝试为使用 spring 引导配置的 spring 批处理/spring 云任务应用程序配置 XA/分布式事务。

我添加了以下依赖项,希望依赖于 spring boot 自动配置:

compile("org.springframework.boot:spring-boot-starter-jta-atomikos")

但是,以下两个类会导致配置两个事务管理器:
  • org.springframework.cloud.task.configuration.SimpleTaskConfiguration
  • org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration

  • 请参阅以下消息:
    2016-07-18 21:46:19.952  INFO 18995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'transactionManager' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration; factoryMethodName=transactionManager; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/batch/core/configuration/annotation/SimpleBatchConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.cloud.task.configuration.SimpleTaskConfiguration; factoryMethodName=transactionManager; initMethodName=null; destroyMethodName=(inferred); defined in org.springframework.cloud.task.configuration.SimpleTaskConfiguration]
    

    然后因为一个 PlatformTransactionManager命名 transactionManager 已配置,我的 atomikos 自动配置没有被拾取:
       AtomikosJtaConfiguration did not match
          - @ConditionalOnClass classes found: org.springframework.transaction.jta.JtaTransactionManager,com.atomikos.icatch.jta.UserTransactionManager (OnClassCondition)
          - @ConditionalOnMissingBean (types: org.springframework.transaction.PlatformTransactionManager; SearchStrategy: all) found the following [transactionManager] (OnBeanCondition)
    

    有人可以帮助我防止这种过度强制 transactionManager 上面两个类引起的beans?

    最佳答案

    我遇到了同样的问题,我的解决方案是实现 BatchConfigurer(保留 @EnableBatchProcessing)并手动添加 atomikos bean。

    作业配置:

    @Configuration
    @EnableBatchProcessing
    public class JobConfig implements BatchConfigurer {
    
        @Autowired
        private DataSource dataSource;
    
        @Autowired
        private JtaTransactionManager jtaTransactionManager;
    
        // ... skipping some code 
    
        @Override
        public JobRepository getJobRepository() throws Exception {
            JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
            factory.setDataSource(dataSource);
            factory.setTransactionManager(jtaTransactionManager);
            return factory.getObject();
        }
    
        @Override
        public PlatformTransactionManager getTransactionManager() throws Exception {
            return jtaTransactionManager;
        }
    
        @Override
        public JobLauncher getJobLauncher() throws Exception {
            SimpleJobLauncher launcher = new SimpleJobLauncher();
            launcher.setJobRepository(getJobRepository());
            launcher.setTaskExecutor(new SimpleAsyncTaskExecutor());
            return launcher;
        }
    
        @Override
        public JobExplorer getJobExplorer() throws Exception {
            JobExplorerFactoryBean jobExplorerFactoryBean = new JobExplorerFactoryBean();
            jobExplorerFactoryBean.setDataSource(dataSource);
            jobExplorerFactoryBean.afterPropertiesSet();
            return jobExplorerFactoryBean.getObject();
        } 
    

    Atomikos配置:
    @Configuration
    public class AtomikosConfig extends AbstractJtaPlatform {
    
        @Bean(initMethod = "init", destroyMethod = "close")
        @DependsOn("atomikosUserTransactionService")
        public UserTransactionManager atomikosTransactionManager() {
                UserTransactionManager manager = new UserTransactionManager();
                manager.setForceShutdown(false);
                manager.setStartupTransactionService(false);
                return manager;
        }
    
        @Bean(initMethod = "init", destroyMethod = "shutdownForce")
        public UserTransactionServiceImp atomikosUserTransactionService() {
                Properties properties = new Properties();
                return new UserTransactionServiceImp(properties);
        }
    
        @Bean
        public UserTransactionImp atomikosUserTransaction() throws SystemException {
                UserTransactionImp transaction = new UserTransactionImp();
                transaction.setTransactionTimeout(300);
                return transaction;
        }
    
        @Primary
        @Bean
        public JtaTransactionManager jtaTransactionManager() throws Exception {
                JtaTransactionManager manager = new JtaTransactionManager();
                manager.setTransactionManager(atomikosTransactionManager());
                manager.setUserTransaction(atomikosUserTransaction());
                manager.setAllowCustomIsolationLevels(true);
                return manager;
        }
    
        @Bean
        public ActiveMQXAConnectionFactory xaFactory() {
                ActiveMQXAConnectionFactory factory = new ActiveMQXAConnectionFactory();
                factory.setBrokerURL("tcp://localhost:61616");
                factory.setUserName("admin");
                factory.setPassword("admin");
                //factory.setTrustAllPackages(true);
                factory.setTransactedIndividualAck(true);
                return factory;
        }
    
        @Bean(initMethod = "init", destroyMethod = "close")
        public AtomikosConnectionFactoryBean connectionFactory() {
                AtomikosConnectionFactoryBean factoryBean = new AtomikosConnectionFactoryBean();
                factoryBean.setUniqueResourceName("amq1");
                factoryBean.setXaConnectionFactory(xaFactory());
                factoryBean.setMaxPoolSize(10);
                return factoryBean;
        }
    
        @Bean
        public AtomikosJtaPlatform springJtaPlatformAdapter() throws Exception {
                AtomikosJtaPlatform platform = new AtomikosJtaPlatform();
                platform.setJtaTransactionManager(jtaTransactionManager());
                platform.setTransactionManager(atomikosTransactionManager());
                platform.setUserTransaction(atomikosUserTransaction());
                return platform;
        }
    
        @Override
        protected TransactionManager locateTransactionManager() {
                return atomikosTransactionManager();
        }
    
        @Override
        protected UserTransaction locateUserTransaction() {
                return atomikosTransactionManager();
        }
    

    关于spring-boot - Spring 云任务的 SimpleTaskConfiguration 和 Spring Batch 的 SimpleBatchConfiguration 防止 XA 事务的 Spring Boot 自动配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38445529/

    相关文章:

    .net检测分布式事务

    java - 如何设计全局分布式事务(无数据库)? JTA 可以用于无数据库事务吗?

    java - 无法在 Spring Boot 2 中绑定(bind) Zipkin 枚举

    java - 如何在不暂停服务器的情况下使用Gradle命令行参数调试Spring Boot?

    spring - spring数据elasticsearch继承没有查询结果

    tomcat - spring 找不到批量初始化 db 脚本

    java - 即使服务器中途出现故障,如何可靠地确保本地和远程数据副本均已更新

    java - Spring 将一个 bean 的属性值注入(inject)另一个 bean

    java - Spring Batch + Spring API REST

    java - spring jdbctemplate 获取字节数组