SimpleTaskConfiguration в облачной задаче Spring и SimpleBatchConfiguration в весеннем пакете, предотвращающие автоматическую настройку весенней загрузки транзакций XA

Я пытаюсь настроить XA/распределенные транзакции для весеннего пакетного/весеннего облачного приложения, настроенного с весенней загрузкой.

Я добавил следующую зависимость, надеясь полагаться на автоматическую настройку весенней загрузки:

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, моя автоматическая настройка атомикоса не подхватывается:

   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)

Может ли кто-нибудь помочь мне предотвратить это неправомерное принудительное использование bean-компонентов transactionManager, вызванное двумя вышеуказанными классами?


person balteo    schedule 18.07.2016    source источник
comment
Можете ли вы предоставить работающий пример (build.gradle и класс приложения), который воспроизводит вашу проблему? Потому что, как и в случае с вашим предыдущим вопросом, без него все, что мы можем сделать, это бросить вам наши догадки и предположения, а затем, в конце концов, ничего не сделать.   -  person Miloš Milivojević    schedule 21.07.2016
comment
Я пытаюсь собрать пример приложения, которое воспроизводит это. Потерпите меня.   -  person balteo    schedule 21.07.2016
comment
Круто, спасибо, это должно упростить устранение неполадок   -  person Miloš Milivojević    schedule 21.07.2016
comment
Вот он: github.com/balteo/atomikosIssue Единственное требование — Docker/Docker-compose и Java .   -  person balteo    schedule 25.07.2016


Ответы (2)


У меня была та же проблема, и мое решение состояло в том, чтобы реализовать BatchConfigurer (сохранив @EnableBatchProcessing) и вручную добавить bean-компоненты atomikos.

Конфигурация работы:

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

АтомикосКонфигурация:

@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();
    }
person rhorvath    schedule 26.08.2016

Посмотрев на ваш пример, я могу сказать вам следующее: нет никакого способа заставить автоконфигурацию работать, даже если вы отключите автоконфигурацию для управления транзакциями, что вы пытались, автоконфигурации задач и пакетов (запущенные @EnableBatchProcessing и @EnableTask) по-прежнему будут регистрировать свои собственные менеджеры транзакций и, таким образом, предотвращать запуск Atomikos Configuration. Причина этого в том, что @EnableBatchProcessing включает в себя класс конфигурации BatchConfigurationSelector, который, в свою очередь, включает либо SimpleBatchConfiguration, либо ModularBatchConfiguration, и оба они всегда будут регистрировать диспетчер транзакций - ни в одном из определений bean-компонентов нет условных аннотаций. @EnableTask делает то же самое, только с SimpleTaskConfiguration.

Таким образом, единственный выход из этого, который я вижу, — это полностью вручную создавать конфигурации пакетов и задач.

Что касается того, как вручную настроить пакет и задачи, я бы рекомендовал посмотреть SimpleTaskConfiguration и AbstractBatchConfiguration — вы можете увидеть там все бобы, которые вам нужно зарегистрировать.

Кроме того, вы можете увидеть пакетный пример на этой странице Java Code Geeks. вам следует просто преобразовать конфигурацию XML в конфигурацию Java.

person Miloš Milivojević    schedule 26.07.2016
comment
Это действительно единственный способ? Если это так, можете ли вы предоставить инструкции или указатели на документацию о том, как создавать конфигурации пакетов и задач? - person balteo; 26.07.2016
comment
Да, я добавил ссылки в свой ответ; в основном, просто обратитесь к классам SimpleTaskConfiguration и AbstractBatchConfiguration, чтобы увидеть, какие bean-компоненты вам нужно определить вручную. - person Miloš Milivojević; 26.07.2016