6

Ich versuche, XA/verteilte Transaktionen für eine Spring-Batch-/Spring-Cloud-Taskanwendung mit Spring Boot zu konfigurieren.SimpleTaskConfiguration für die SimpleTaskConfiguration und SpringBatches SimpleTaskConfiguration verhindert die automatische Konfiguration von XA-Transaktionen für den Spring Cloud-Vorgang

Ich habe hinzugefügt, um die folgende Abhängigkeit von Feder Boot-Autokonfiguration verlassen hofft:

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

jedoch die folgenden zwei Klassen zwei Transaktionsmanager verursachen konfiguriert werden:

  • org.springframework.cloud.task.configuration.SimpleTaskConfiguration

  • org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration

folgende Meldung:

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] 

und dann, weil ein PlatformTransactionManager namens transactionManager konfiguriert ist, wird meine atomikos Auto-Konfiguration nicht abgeholt:

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) 

Kann jemand bitte helfen Sie mir Verhindern Sie, dass die transactionManager Bohnen, die durch die beiden obigen Klassen verursacht werden, übermäßig forciert werden?

+0

Können Sie ein lauffähiges Beispiel (build.gradle und eine Anwendungsklasse), die Ihr Problem reproduziert? Denn wie bei Ihrer vorherigen Frage können wir ohne Sie nur unsere Vermutungen und Annahmen auf Sie werfen und dann am Ende nichts tun. –

+0

Ich versuche eine Beispiel-App zusammenzustellen, die das reproduziert. Trage mit mir. – balteo

+0

Cool, danke, das sollte es einfacher machen, Fehler zu beheben –

Antwort

1

Wenn ich mir Ihr Beispiel anschaue, kann ich Ihnen Folgendes sagen: Es gibt keine Möglichkeit, die automatische Konfiguration durchzuführen - selbst wenn Sie die automatische Konfiguration für die Transaktionsverwaltung deaktivieren, die Sie versucht haben, Task und Batch-Auto. Konfigurationen (ausgelöst durch @EnableBatchProcessing und @EnableTask) würden immer noch ihre eigenen Transaktionsmanager registrieren und somit Atomikos-Konfiguration daran hindern, ausgelöst zu werden. Der Grund dafür ist, dass @EnableBatchProcessing die Konfigurationsklasse BatchConfigurationSelector enthält, die wiederum entweder SimpleBatchConfiguration oder ModularBatchConfiguration enthält und beide immer einen Transaktionsmanager registrieren - es gibt keine bedingten Anmerkungen zu einer der Bean-Definitionen. @EnableTask macht eine sehr ähnliche Sache, nur mit SimpleTaskConfiguration.

Der einzige Ausweg, den ich sehen kann, ist für Sie, Batch- und Task-Konfigurationen vollständig manuell zu erstellen.

Zum manuellen Konfigurieren von Batch und Aufgaben würde ich empfehlen, SimpleTaskConfiguration und AbstractBatchConfiguration zu betrachten - Sie können dort alle Beans sehen, die Sie registrieren müssen.

Alternativ können Sie ein Stapelbeispiel on this Java Code Geeks page sehen, Sie sollten nur die XML-Konfiguration in Java-Konfiguration übersetzen.

+0

Ist das wirklich der einzige Weg? Wenn dies der Fall ist, können Sie Anweisungen oder Hinweise zur Dokumentation zum Erstellen von Batch- und Taskkonfigurationen bereitstellen? – balteo

+0

Ja, ich habe die Links zu meiner Antwort hinzugefügt; Im Grunde genommen, beziehen Sie sich einfach auf die SimpleTaskConfiguration- und AbstractBatchConfiguration-Klassen, um zu sehen, welche Beans Sie manuell definieren müssen. –

2

Ich hatte das gleiche Problem und meine Lösung war BatchConfigurer zu implementieren (Keeping @ EnableBatchProcessing) und atomikos Bohnen manuell hinzufügen.

JobConfig:

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

AtomikosConfig:

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