Transaction contract in HornetQ Resource Adapter is broken
jmesnil Sep 19, 2012 9:24 AMI've been working on making the HornetQ RA works in AS7 standalone.
The maing goal is to be able to consume messages in a MDB from a remote JMS server.
The secondary goal is to validate that we can use the HornetQ RA in any app server (starting with AS7 standalone as the first candidate)
I track this with HORNETQ-1030.
First blocker was that the hornetq-ra.rar does not contain all the required jars (netty was missing)
Second blocker is that HornetQ RA requires to be able to locate the app server transaction manager to support transactions.
After reading again (and again and again!) the JCA 1.6 spec, I think this dependency is wrong. in figure 7.4 of the spect, the only thing that the RA must expose is a LocalTransaction and XAResource.
But there is no arrow that links the RA to the transaction manager. Looking at the HornetQ ra code, we need the TM to check whether there is an active transaction, flag the tx as rollback only or set its timeout.
We don't need the TM to know if there is an active tx, we can have a flag which is updated for every call to start/prepare/commit, etc.
In the same order, I don't think it is right for a *XA resource* to flag the tx as rollback only. When we encounter such a condition, we should throw the correct XAException from prepare instead.
And I don't see why a XA Resource has to change the tx timeout. What if another XA resource (like a JDBC connection) would do the same when it is enlisted after HornetQ RA?
Currently, when the RA is deployed in JBoss AS5 or AS7, it has a hack to locate the TM using a static locator method specific to the app server. This goes agains the JCA spec which was to avoid N*M deployment cases.
(there is a separate use case to be able to support auto recovery which also requires a hack to locate AS7 specific classes)
I think this dependency from HornetQ RA (and *core*) to a transaction manager is incorrect. We should not require a TM (which manage the tx boundaries) to be able to implement correctly a XA resource.
The RA's HornetQMessageHandler is instantiated with a TM to check whether the handler is in a XA transaction without a TM. I don't think we have to have that code, let's be a good XA resource citizen and let the TM handle the transaction...
We want to have a HornetQ RA that can be deployed in *any* JCA-compliant app server. Require hacks for every one of this app server is not the correct solution. Let's get rid of this dependency to the TM and we will make the RA much more simpler to deploy.
wdyt?