Hi.
I'm using gf 3.1.2, and am porting an existing j2ee app for it.
The app (servlet) has the following logic when it comes to XA transactions:
When the servlet logic needs a database connection, it requests a
transaction (TransactionManager.getTransaction()) and a connection (looking
up the connection from JNDI data source). It then also associates the
connection to the transaction
using TransactionSynchronizationRegistry.putResource() with a custom key.
If servlet needs to commit the transaction, it does it explicitly.
For this servlet, there is a request listener which implements
requestDestroyed(), at which time it looks up the current transaction, if
exists, and rolls back the transaction and closes the connection associated
with that transaction (using getResource() to get the connection).
This all worked fine on some other respected application server.
Glassfish seems to manage the transactions differently, and commits them
automatically when the request finishes processing. So, when it comes to
the request listener, there is already no actual transaction on the thread,
and attempt to clean up fails. The connection also remains open (I see leak
detection notifications on those); it seems that even if a connection is
part of a transaction, it's not automatically closed when the transaction
finishes.
I changed the connection pool to set "allow non-component callers" to true.
After this change, the transaction is no longer committed when the request
finishes (at least I see that if a request changed the database, these
changes are not in the DB, and there are no unfinished prepared transaction
left in the DB), so I guess it's just rolled back or otherwise dismissed.
But still, when it comes to the request listener, there is no transaction
on the thread by that time. TransactionManager.getResource() throws an
IllegalStateException.
Is there a way to tell GlassFish to never automatically manage XA
connections from any given XA pool, and let application explicitly commit
or roll it back in all cases?