Почему Remote Weblogic JMS не участвует в транзакции XA при весенней загрузке?

Я работаю над приложением с весенней загрузкой, где мне нужен XA, чтобы гарантировать, что обновления JPA и генерация сообщений JMS - это либо все, либо ничего. Проблема в том, что когда происходит откат, откатывается БД, но не сообщение JMS.

Я работаю со встроенным tomcat, а сервер JMS - Weblogic12c.

Я следовал указаниям JTA из spring- загрузочную документацию и добавил зависимости для Atomikos (transactions-jms, transactions-jta, transactions-jdbc), а также spring-boot-starter-jta-atomikos.

В журналах я вижу, что Atomikos работает и что-то вроде запросов JPA добавляется к транзакции XA, но ничего для JMS.

Приведенные ниже журналы взяты из кода, в котором я выполняю обновления JPA, затем отправляю сообщение JMS, используя JMSTemplate, затем выбрасываю RuntimeException:

INFO  c.a.jdbc.AbstractDataSourceBean - AtomikosDataSoureBean 'dataSource': getConnection ( null )...   
INFO  c.a.jdbc.AbstractDataSourceBean - AtomikosDataSoureBean 'dataSource': init...   
INFO  c.a.i.imp.CompositeTransactionImp - addParticipant ( XAResourceTransaction: 31302E33302E36302E3137332E746D30303030313030303434:31302E33302E36302E3137332E746D31 ) for transaction 10.30.60.173.tm0000100044   
INFO  c.a.d.xa.XAResourceTransaction - XAResource.start ( 31302E33302E36302E3137332E746D30303030313030303434:31302E33302E36302E3137332E746D31 , XAResource.TMJOIN ) on resource dataSource represented by XAResource instance oracle.jdbc.driver.T4CXAResource@621c7c98   
INFO  c.a.i.imp.CompositeTransactionImp - registerSynchronization ( com.atomikos.jdbc.AtomikosConnectionProxy$JdbcRequeueSynchronization@f4a9582b ) for transaction 10.30.60.173.tm0000100044   
INFO  c.a.jdbc.AtomikosConnectionProxy - atomikos connection proxy for oracle.jdbc.driver.LogicalConnection@650a9087: calling prepareStatement(select prjct_rvsn_seq_num_seq.nextval from dual)...   
INFO  c.a.jdbc.AtomikosConnectionProxy - atomikos connection proxy for oracle.jdbc.driver.LogicalConnection@650a9087: isClosed()...   
INFO  c.a.jdbc.AtomikosConnectionProxy - atomikos connection proxy for oracle.jdbc.driver.LogicalConnection@650a9087: calling getWarnings...   
INFO  c.a.jdbc.AtomikosConnectionProxy - atomikos connection proxy for oracle.jdbc.driver.LogicalConnection@650a9087: calling clearWarnings...   
INFO  c.a.jdbc.AtomikosConnectionProxy - atomikos connection proxy for oracle.jdbc.driver.LogicalConnection@650a9087: close()...   
INFO  c.a.d.xa.XAResourceTransaction - XAResource.end ( 31302E33302E36302E3137332E746D30303030313030303434:31302E33302E36302E3137332E746D31 , XAResource.TMSUCCESS ) on resource dataSource represented by XAResource instance oracle.jdbc.driver.T4CXAResource@621c7c98   
INFO  c.c.ola.order.service.OrderService - Order saved of scope:FIRST with app ID:1127662    
INFO  c.c.o.o.s.OrderEventBroadcaster - Sending message  on queue jms/AppQueue   
DEBUG o.s.jms.core.JmsTemplate - Executing callback on JMS Session: weblogic.jms.client.WLSessionImpl@24cfb8e8   
DEBUG o.s.j.s.d.JndiDestinationResolver - Located object with JNDI name [jms/AppQueue]   
DEBUG o.s.jms.core.JmsTemplate - Sending created message: TextMessage[null, <?xml version="1.0" encoding="...]   
INFO  c.a.d.xa.XAResourceTransaction - XAResource.rollback ( 31302E33302E36302E3137332E746D30303030313030303434:31302E33302E36302E3137332E746D31 ) on resource dataSource represented by XAResource instance oracle.jdbc.driver.T4CXAResource@621c7c98   
INFO  com.atomikos.icatch.jta.Sync2Sync - afterCompletion ( STATUS_ROLLEDBACK ) called  on Synchronization: org.hibernate.resource.transaction.backend.jta.internal.synchronization.RegisteredSynchronization@25385341   
INFO  c.a.i.imp.CompositeTransactionImp - rollback() done of transaction 10.30.60.173.tm0000100044  

В моем гугле я не видел многого. Кажется, что это должно просто работать, но это не то, где я уронил мяч?

ОБНОВЛЕНИЕ:

Ниже показано, как я создаю свой ConnectionFactory:

@Bean
FactoryBean<ConnectionFactory> jmsConnectionFactory(final JndiTemplate jndiTemplate) {
    final JndiObjectFactoryBean beanFactory = new JndiObjectFactoryBean();

    beanFactory.setJndiTemplate(jndiTemplate);
    beanFactory.setJndiName("jms.remoteConnectionFactory");
    beanFactory.setProxyInterface(ConnectionFactory.class);

    return (FactoryBean) beanFactory;
}

ОБНОВЛЕНИЕ:

Поскольку журналы ссылались на weblogic.jms.client.WLSessionImpl, а не на что-то с «XA» в имени, я исследовал, что возвращает weblogic. Экземпляр, возвращенный из "jms.remoteConnectionFactory", был weblogic.jms.client.JMSXAConnectionFactory, который не реализует javax.jms.XAConnectionFactory, что кажется странным. Я не знаю, почему это так или это проблема, но похоже, что это может быть.


person pgreen2    schedule 12.07.2016    source источник
comment
Как вы настроили JMS? Я предполагаю, что вы по какой-то причине не работаете с фабрикой соединений XA.   -  person Andy Wilkinson    schedule 13.07.2016
comment
Я просто проверял это. Я вижу в дереве JNDI веб-логики, что jms.remoteConnectionFactory (именно так я создаю свою ConnectionFactory) имеет тип weblogic.jms.client.JMSXAConnectionFactory. Однако не похоже, что он реализует javax.jms.XAConnectionFactory, но я не знаю, является ли это проблемой.   -  person pgreen2    schedule 13.07.2016


Ответы (1)


Мое решение состояло в том, чтобы установить sessionTransacted в true на jmsTemplate.

@Bean
JmsTemplate cciSitesJmsTemplate(@CciSites final ConnectionFactory connectionFactory, final JndiDestinationResolver destinationResolver) {
    final JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
    jmsTemplate.setDestinationResolver(destinationResolver);
    // NOTE: sessionTransacted is required to join the XA transaction
    jmsTemplate.setSessionTransacted(true);
    return jmsTemplate;
}
person pgreen2    schedule 13.07.2016