1
votes

I am trying to configure my custom ActiveMQ producer to use XA transaction. Unfortunately it does't work as expected because messages are sent to queue immediately instead of waiting for transactions to commit.

Here is the producer:

public class MyProducer {

    @Autowired
    @Qualifier("myTemplate")
    private JmsTemplate template;

    @Transactional
    public void sendMessage(final Order order) {
        template.send(new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                ObjectMessage message = new ActiveMQObjectMessage();
                message.setObject(order);
                return message;
            }
        });
    }
}

And this is template and connection factory configuration:

<bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
      <property name="jndiName" value="java:/activemq/ConnectionFactory" />
</bean>

<bean id="myTemplate" class="org.springframework.jms.core.JmsTemplate"
      p:connectionFactory-ref="jmsConnectionFactory"
      p:defaultDestination-ref="myDestination"
      p:sessionTransacted="true"
      p:sessionAcknowledgeModeName="SESSION_TRANSACTED" />

As you can see I am using ConnectionFactory initiated via JNDI. It is configured on JBoss EAP 6.3:

    <subsystem xmlns="urn:jboss:domain:resource-adapters:1.1">
        <resource-adapters>
            <resource-adapter id="activemq-rar.rar">
                <module slot="main" id="org.apache.activemq.ra"/>
                <transaction-support>XATransaction</transaction-support>
                <config-property name="ServerUrl">
                    tcp://localhost:61616
                </config-property>
                <connection-definitions>
                    <connection-definition class-name="org.apache.activemq.ra.ActiveMQManagedConnectionFactory" jndi-name="java:/activemq/ConnectionFactory" enabled="true" use-java-context="true" pool-name="ActiveMQConnectionFactoryPool" use-ccm="true">
                        <xa-pool>
                            <min-pool-size>1</min-pool-size>
                            <max-pool-size>20</max-pool-size>
                        </xa-pool>
                    </connection-definition>
                </connection-definitions>
            </resource-adapter>
        </resource-adapters>
    </subsystem>

When I debug I can see that JmsTemplate is configured properly:

  • it has a reference to valid connection factory org.apache.activemq.ra.ActiveMQConnectionFactory
  • connection factory has a reference to valid transaction manager: org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl
  • session transacted is set to true
  • session acknowledge mode is set to SESSION_TRANSACTED(0)

Do you have any idea why these messages are pushed to the queue immediately and they are not removed when transaction is rolled back (e.g. when I throw exception at the end of "sendMessage" method?

1

1 Answers

1
votes

You need to show the rest of your configuration (transaction manager etc).

It looks like you don't have transactions enabled in the application context so the template is committing the transaction itself.

Do you have <tx:annotation-driven/> in the context?