users@glassfish.java.net

Cannot prepare XA Transaction with ActiveMQ broker

From: <glassfish_at_javadesktop.org>
Date: Thu, 13 Mar 2008 06:46:09 PST

Hi,

I am working on integrating the ActiveMQ resource adapter with glassfish v2 UR1. I have set up a simple XA test case where I am updating a local Derby DB and an ActiveMQ message queue managed by the resource adapter connection pool.

The XA transaction works well up to the moment the [i]prepare[/i] is issued by the TransactionManager. The ActiveMQ broker then complains that it cannot prepare a transaction that has not been started before. After a lot of debugging I have traced the problem down to this:

when my client code has made the DB update and written the message to the queue, it closes the javax.jms.Connection, thus returning it to the glassfish managed connection pool. This happens by notifying the [i]com.sun.enterprise.resource.ConnectorAllocator$ConnectionListenerImpl.connectionClosed()[/i] method. This method then decreases the resource's [i]sharedCount[/i] and returns it to the connection pool by invoking [i]com.sun.enterprise.resource.PoolManagerImpl.resourceClosed(resource)[/i] which in turn calls [i]putbackResourceToPool()[/i] which eventually invokes [i]com.sun.enterprise.resource.AbstractConnectorAllocator.cleanup()[/i]. The cleanup method then retrieves the underlying ActiveMQManagedConnection and invokes its [i]cleanup()[/i] method which is then closing the logical connection to the ActiveMQ broker which is why the subsequent [i]xa_prepare[/i] fails in ActiveMQ since it has already thrown away the transactional context since the connection has been closed!
  already.

I think the problem lies within glassfish's connection pool implementation. The JCA specification states in the [i]javax.resource.spi.ManagedConnection.cleanup()[/i] API docs:

"The cleanup of ManagedConnection is always driven by an application server. An application server should not invoke ManagedConnection.cleanup when there is an uncompleted transaction (associated with a ManagedConnection instance) in progress."

However, this seems to be exactly what is happening here, isn't it?
I have not yet found any code in the PoolManagerImpl and/or ResourceManagerImpl checking for any transactions being in progress. Instead, the cleanup() method is always invoked. Is this intended behavior?

Any thoughts?

Kai
[Message sent by forum member 'hudalla' (hudalla)]

http://forums.java.net/jive/thread.jspa?messageID=263812