6

Sto tentando di configurare XA/transazioni distribuite per un'applicazione di attività Spring/Spring Cloud configurata con avvio a molla.SimpleTaskConfiguration di Spring Cloud Task e SimpleBatchConfiguration del batch di primavera che impedisce la configurazione automatica di avvio a molla delle transazioni XA

ho aggiunto la seguente dipendenza sperando di contare su configurazione automatica di avvio di primavera:

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

Tuttavia le seguenti due classi causano due gestori di transazioni da configurare:

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

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

Vedi seguente messaggio:

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] 

e poi perché un PlatformTransactionManager chiamato transactionManager è configurato, il mio atomikos configurazione automatica non viene prelevato:

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) 

Qualcuno può per favore mi aiuti prevenire questo indebitamente forzare i fagioli transactionManager causati dalle due classi sopra?

+0

Potete fornire un esempio eseguibile (build.gradle ed una classe di applicazione) che riproduce il tuo problema? Perché, come con la tua domanda precedente, senza di essa tutto ciò che possiamo fare è gettare le tue ipotesi e supposizioni su di te e alla fine non fare nulla. –

+0

Sto provando a mettere insieme un'app campione che riproduca questo. Sopportami. – balteo

+0

Cool, grazie, che dovrebbe facilitare la risoluzione dei problemi –

risposta

1

Dopo aver esaminato il tuo esempio, quello che posso dire è questo: non c'è modo di far funzionare la configurazione automatica, anche se si disabilita l'auto-configurazione per la gestione delle transazioni, cosa che hai provato, attività e batch auto- le configurazioni (attivate da @EnableBatchProcessing e @EnableTask) registrano ancora i propri gestori delle transazioni e quindi impediscono l'attivazione di Atomikos Configuration. La ragione di ciò è dovuta al fatto che @EnableBatchProcessing include la classe di configurazione BatchConfigurationSelector, che a sua volta include SimpleBatchConfiguration o ModularBatchConfiguration ed entrambi registreranno sempre un gestore transazioni - non ci sono annotazioni condizionali su nessuna delle definizioni di bean. @EnableTask fa una cosa molto simile, solo con SimpleTaskConfiguration.

Quindi, l'unica via di uscita che posso vedere è che crei le configurazioni batch e di attività completamente manualmente.

Per quanto riguarda la configurazione manuale di batch e attività, è consigliabile consultare SimpleTaskConfiguration e AbstractBatchConfiguration - è possibile visualizzare tutti i bean che è necessario registrare.

In alternativa, è possibile visualizzare un esempio di lotto on this Java Code Geeks page, è sufficiente convertire la configurazione XML in configurazione Java.

+0

È davvero l'unico modo? In tal caso, è possibile fornire istruzioni o riferimenti alla documentazione su come creare configurazioni batch e task? – balteo

+0

Sì, ho aggiunto i collegamenti alla mia risposta; in pratica, fai semplicemente riferimento alle classi SimpleTaskConfiguration e AbstractBatchConfiguration per vedere quali bean devi definire manualmente. –

2

Ho avuto lo stesso problema e la mia soluzione era implementare BatchConfigurer (mantenendo @EnableBatchProcessing) e aggiungere manualmente i fagioli atomikos.

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