The standard JTA approach to enlisting XA resources is to add the XA resource
explicitly to the current javax.transaction.Transaction object
(representing the current transaction). In other words, you must explicitly enlist an XA
resource every time a new transaction starts.
Enlisting an XA resource with a transaction simply involves invoking the
enlistResource() method on the Transaction interface. For example, given
a TransactionManager object and an XAResource object, you
could enlist the XAResource object as follows:
// Java import javax.transaction.Transaction; import javax.transaction.TransactionManager; import javax.transaction.xa.XAResource; ... // Given: // 'tm' of type TransactionManager // 'xaResource' of type XAResource // Start the transaction tm.begin(); Transaction transaction = tm.getTransaction(); transaction.enlistResource(xaResource); // Do some work... ... // End the transaction tm.commit();
The tricky aspect of enlisting resources is that the resource must be enlisted on
every new transaction and the resource must be enlisted
before you start to use the resource. If you enlist resources
explicitly, you could end up with error-prone code that is littered with
enlistResource() calls. Moreover, sometimes it can be difficult to call
enlistResource() in the right place (for example, if you are using a
framework that hides some of the transaction details).
For these reasons, it is much easier (and safer) in practice to use features that support auto-enlistment of XA resources. For example, in the context of using JMS and JDBC resources, the standard technique is to use wrapper classes that support auto-enlistment.
The way to perform auto-enlisting of a JMS XA resource is to implement a wrapper
class of type, javax.jms.ConnectionFactory. You can then implement this
class, so that every time a new connection is created, the JMS XA resource is enlisted
with the current transaction.
Apache ActiveMQ provides the wrapper class, XaPooledConnectionFactory, which
implements auto-enlistment for you and, additionally, implements JMS connection pooling
for better performance. To use the XaPooledConnectionFactory wrapper class,
simply create an instance that takes a reference to an XA connection factory instance
(for example, ActiveMQXAConnectionFactory) and also provide a reference to
the transaction manager (which is used to enlist the resource).
For example, the following example shows how you can use Spring XML to define an
auto-enlisting JMS connection factory (with the bean ID,
jmsXaPoolConnectionFactory):
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:osgi="http://www.springframework.org/schema/osgi"
...>
...
<!-- access through JTA TransactionManager -->
<osgi:reference id="osgiJtaTransactionManager"
interface="javax.transaction.TransactionManager"/>
...
<!-- connection factory wrapper to support auto-enlisting of XA resource -->
<bean id="jmsXaPoolConnectionFactory"
class="org.apache.activemq.pool.XaPooledConnectionFactory">
<property name="maxConnections" value="1" />
<property name="connectionFactory" ref="jmsXaConnectionFactory" />
<property name="transactionManager" ref="osgiJtaTransactionManager" />
</bean>
<bean id="jmsXaConnectionFactory"
class="org.apache.activemq.ActiveMQXAConnectionFactory">
<property name="brokerURL" value="vm:local"/>
<property name="redeliveryPolicy">
<bean class="org.apache.activemq.RedeliveryPolicy">
<property name="maximumRedeliveries" value="0"/>
</bean>
</property>
</bean>
...
</beans>







