首页 > 解决方案 > SpringBoot using JMS (OracleAQ) + SpringData JPA transaction timeout issue

问题描述

I'm using springboot to consume a JMS message (from oracle AQ) do some stuff using atomikos and SpringData JPA.

It is working fine except when the transaction timeout is reached. Everything done using JPA is commited but the JMS message goes to the exception queue.

My expected behaviour is to rollback both JMS message AND JPA operations and stop with the same error I currently get. Beside that I also wanted to understand how I can have partial commit within (what looks like) one transaction opened (see log below) ?

Code is as simple as that :

// if this method take more than the transation timeout
// then everything done using JPA in commited but the JMS message goes to the exception QUEUE
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void execute(String... args) {

   // Consume message from queue and get the associated object from database using JPA
   T object = this.read();

   // process this object
   this.process(object);

}

I put everything in DEBUG, and see nothing relevant in log :

16/04/2020 15:33:33.459 [main] DEBUG com.atomikos.icatch.imp.CompositeTransactionManagerImp - createCompositeTransaction ( 50000 ): created new ROOT transaction with id 50.157.120.30.tm158704401345900002
-- SOMETHING TAKING LONG TIME HERE
16/04/2020 15:34:23.747 [Atomikos:2] WARN  com.atomikos.icatch.imp.ActiveStateHandler - Transaction 50.157.120.30.tm158704401345900002 has timed out and will rollback.
-- SOMETHING TAKING LONG TIME HERE
16/04/2020 15:33:33.462 [main] DEBUG com.atomikos.icatch.imp.CompositeTransactionImp - registerSynchronization ( com.atomikos.icatch.jta.Sync2Sync@af0f99a9 ) for transaction 50.157.120.30.tm158704401345900002
16/04/2020 15:35:18.025 [main] DEBUG com.atomikos.icatch.imp.CompositeTransactionImp - commit() done (by application) of transaction 50.157.120.30.tm158704401345900002

Here is my configuration

@Bean
public DataSource dataSource() throws SQLException {
    // Also tried with :
    // OracleXADataSource dataSource = new OracleXADataSource();
    OracleConnectionPoolDataSource dataSource = new OracleConnectionPoolDataSource();
    dataSource.setURL(url);
    dataSource.setUser(login);
    dataSource.setPassword(password);
    return dataSource;
}

@Bean
public ConnectionFactory connectionFactory(DataSource datasource) throws JMSException, SQLException {
    return AQjmsFactory.getQueueConnectionFactory(datasource);

    // Also tried with :
    /*
    XAQueueConnectionFactory xacf = AQjmsFactory.getXAQueueConnectionFactory(dataSource());
    AtomikosConnectionFactoryBean qcf = new AtomikosConnectionFactoryBean();
    qcf.setUniqueResourceName("MYDS");
    qcf.setXaConnectionFactory(xacf);
    return qcf;
    */
}

@Bean
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
    JmsTemplate jmsTemplate = new JmsTemplate();
    jmsTemplate.setConnectionFactory(connectionFactory);
    SimpleMessageConverter converter = new SimpleMessageConverter();
    jmsTemplate.setMessageConverter(converter);
    jmsTemplate.setSessionTransacted(true);
    jmsTemplate.setDefaultDestinationName("AQADMIN.MYQUEUE");
    return jmsTemplate;
}

And the full stacktrace

org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException: Rolled back already.
                at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1037) ~[spring-tx-5.1.2.RELEASE.jar!/:5.1.2.RELEASE]
                at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:746) ~[spring-tx-5.1.2.RELEASE.jar!/:5.1.2.RELEASE]
                at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714) ~[spring-tx-5.1.2.RELEASE.jar!/:5.1.2.RELEASE]
                at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:533) ~[spring-tx-5.1.2.RELEASE.jar!/:5.1.2.RELEASE]
                at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:304) ~[spring-tx-5.1.2.RELEASE.jar!/:5.1.2.RELEASE]
                at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.2.RELEASE.jar!/:5.1.2.RELEASE]
                at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.2.RELEASE.jar!/:5.1.2.RELEASE]
                at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.1.2.RELEASE.jar!/:5.1.2.RELEASE]
                at my.package.batch.indicateurs.calcul.BatchCalculerIndicateurs$$EnhancerBySpringCGLIB$$81a5c815.execute(<generated>) ~[classes!/:4.1.0-SNAPSHOT]
                at my.package.framework.MyBatchLauncher.execute(MyBatchLauncher.java:99) ~[brm-batch-frameworkspring-4.1.0-SNAPSHOT.jar!/:4.1.0-SNAPSHOT]
                at my.package.framework.MyBatchLauncher.runBatch(MyBatchLauncher.java:66) ~[brm-batch-frameworkspring-4.1.0-SNAPSHOT.jar!/:4.1.0-SNAPSHOT]
                at my.package.framework.MyBatchLauncher.run(MyBatchLauncher.java:44) ~[brm-batch-frameworkspring-4.1.0-SNAPSHOT.jar!/:4.1.0-SNAPSHOT]
                at my.package.framework.MyCommandLineRunner.lambda$commandLineRunner$0(MyCommandLineRunner.java:55) ~[brm-batch-frameworkspring-4.1.0-SNAPSHOT.jar!/:4.1.0-SNAPSHOT]
                at my.package.framework.MyCommandLineRunner$$Lambda$525.0000000085F87050.run(Unknown Source) ~[?:?]
                at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:813) [spring-boot-2.1.0.RELEASE.jar!/:2.1.0.RELEASE]
                at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:797) [spring-boot-2.1.0.RELEASE.jar!/:2.1.0.RELEASE]
                at org.springframework.boot.SpringApplication.run(SpringApplication.java:324) [spring-boot-2.1.0.RELEASE.jar!/:2.1.0.RELEASE]
                at my.package.framework.MyCommandLineRunner.main(MyCommandLineRunner.java:40) [brm-batch-frameworkspring-4.1.0-SNAPSHOT.jar!/:4.1.0-SNAPSHOT]
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0]
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95) ~[?:1.8.0]
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55) ~[?:1.8.0]
                at java.lang.reflect.Method.invoke(Method.java:508) ~[?:1.8.0]
                at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [CalculerIndicateurs-4.1.0-SNAPSHOT.jar:4.1.0-SNAPSHOT]
                at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [CalculerIndicateurs-4.1.0-SNAPSHOT.jar:4.1.0-SNAPSHOT]
                at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [CalculerIndicateurs-4.1.0-SNAPSHOT.jar:4.1.0-SNAPSHOT]
                at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) [CalculerIndicateurs-4.1.0-SNAPSHOT.jar:4.1.0-SNAPSHOT]
Caused by: javax.transaction.RollbackException: Rolled back already.
                at com.atomikos.icatch.jta.TransactionImp.rethrowAsJtaRollbackException(TransactionImp.java:48) ~[transactions-jta-4.0.6.jar!/:?]
                at com.atomikos.icatch.jta.TransactionImp.commit(TransactionImp.java:188) ~[transactions-jta-4.0.6.jar!/:?]
                at com.atomikos.icatch.jta.TransactionManagerImp.commit(TransactionManagerImp.java:414) ~[transactions-jta-4.0.6.jar!/:?]
                at com.atomikos.icatch.jta.UserTransactionManager.commit(UserTransactionManager.java:159) ~[transactions-jta-4.0.6.jar!/:?]
                at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1034) ~[spring-tx-5.1.2.RELEASE.jar!/:5.1.2.RELEASE]
                ... 25 more
Caused by: com.atomikos.icatch.RollbackException: Rolled back already.
                at com.atomikos.icatch.imp.CoordinatorStateHandler.commitFromWithinCallback(CoordinatorStateHandler.java:393) ~[transactions-4.0.6.jar!/:?]
                at com.atomikos.icatch.imp.ActiveStateHandler$6.doCommit(ActiveStateHandler.java:268) ~[transactions-4.0.6.jar!/:?]
                at com.atomikos.icatch.imp.CoordinatorStateHandler.commitWithAfterCompletionNotification(CoordinatorStateHandler.java:581) ~[transactions-4.0.6.jar!/:?]
                at com.atomikos.icatch.imp.ActiveStateHandler.commit(ActiveStateHandler.java:263) ~[transactions-4.0.6.jar!/:?]
                at com.atomikos.icatch.imp.CoordinatorImp.commit(CoordinatorImp.java:548) ~[transactions-4.0.6.jar!/:?]
                at com.atomikos.icatch.imp.CoordinatorImp.terminate(CoordinatorImp.java:685) ~[transactions-4.0.6.jar!/:?]
                at com.atomikos.icatch.imp.CompositeTransactionImp.commit(CompositeTransactionImp.java:282) ~[transactions-4.0.6.jar!/:?]
                at com.atomikos.icatch.jta.TransactionImp.commit(TransactionImp.java:172) ~[transactions-jta-4.0.6.jar!/:?]
                at com.atomikos.icatch.jta.TransactionManagerImp.commit(TransactionManagerImp.java:414) ~[transactions-jta-4.0.6.jar!/:?]
                at com.atomikos.icatch.jta.UserTransactionManager.commit(UserTransactionManager.java:159) ~[transactions-jta-4.0.6.jar!/:?]
                at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1034) ~[spring-tx-5.1.2.RELEASE.jar!/:5.1.2.RELEASE]
                ... 25 more

I'm feeling I'm missing something in the atomikos configuration but can't find what.

Thanks for your help.

标签: springspring-bootjpaspring-jmsatomikos

解决方案


推荐阅读