简体   繁体   中英

activeMQ does not participate in Weblogic XA transactions

I try to get XA transactions involving a jdbc and jms DataSource working in a Spring webapp deployed to Weblogic.

Using a local Atomikos TransactionManager, this works - I see XA debug messages in ActiveMQ, and stuff stays consistent. In Weblogic however, the database and ActiveMQ are not transactionally consistent.

I have added a foreign JMS server in Weblogic

JNDI Initial Context Factory:

org.apache.activemq.jndi.ActiveMQInitialContextFactory

JNDI Connection URL:

tcp://localhost:61616

JNDI Properties:

connectionFactoryNames=XAConnectionFactory

To that server, I have added a ConnectionFactory (Remote JNDI Name = XAConnectionFactory). Lookups work, so far so good.

In my code, this is how I setup the Spring JTA:

@Override
   @Bean
   @Profile(AppConfig.PROFILE_WEBLOGIC)
   public JtaTransactionManager transactionManager()
   {
      WebLogicJtaTransactionManager tx = new WebLogicJtaTransactionManager();
      tx.afterPropertiesSet();

      return tx;
   }

And this is my JMS config:

   @Bean
   @Profile(AppConfig.PROFILE_WEBLOGIC)
   public ConnectionFactory connectionFactory()
   {
      Properties props = new Properties();
      props.put(Context.INITIAL_CONTEXT_FACTORY, env.getProperty(Context.INITIAL_CONTEXT_FACTORY));
      props.setProperty(Context.PROVIDER_URL, env.getProperty(Context.PROVIDER_URL));

      try
      {
         InitialContext ctx = new InitialContext(props);
         ActiveMQXAConnectionFactory connectionFactory = (ActiveMQXAConnectionFactory) ctx
            .lookup(env.getProperty("jms.connectionFactory"));

         return connectionFactory;
      }
      catch(NamingException e)
      {
         throw new RuntimeException("XAConnectionFactory lookup failed", e);
      }
   }

   @Bean
   public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() throws JMSException
   {
      DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
      factory.setConnectionFactory(connectionFactory());
      factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
      factory.setTransactionManager(txConfig.transactionManager());
      factory.setBackOff(new FixedBackOff());

      return factory;
   }

   @Bean(name = "jmsTemplate")
   @Override
   public JmsTemplate jmsTemplate() throws JMSException
   {
      JmsTemplate t = new JmsTemplate();
      t.setConnectionFactory(connectionFactory());
      t.setMessageTimestampEnabled(true);
      t.setMessageIdEnabled(true);

      return t;
   }

My JMS consumer is annotated with:

@Transactional   
@JmsListener(destination = "test.q1")

Is there anything I am missing?

事实证明,这只能通过资源适配器来实现,而不能仅通过JNDI ConnectionFactory来实现。

It is possible, using the undocumented ActiveMQ JNDI property "xa=true" in the foreign JMS server definition, see here:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM