I have some more thoughts on this:
Daniel John Debrunner wrote:
Yes, but the transaction should be suspended before closing the
logical connection - by calling XAResource.end(xid, TMSUSPEND).
Shouldn't it?
I don't know if the spec requires that. I don't believe Derby
implements it that way, I think you can open and close the logical
JDBC connection freely while in an active global transaction.
The short extract from the JTA Specification:
/"When the application invokes the connection's close method, the resource
adapter invalidates the connection object reference that was held by the
application and
notifies the application server about the close. The transaction manager
should invoke
the XAResource.end method to disassociate the transaction from that
connection."
/
There are more possibilities how to work with XA transaction on a user
level.
1.) Using the UserTransaction interface implementation.
2.) Using the TransactionManager
3.) Directly calling the XAResource methods and manage everything
through XAConnection, XAResource and java.sql.Connection. First the user
have to create XAConnection instance, call the
XAConnection.getXAResource to obtain the XAResource object. The
transaction managed through the XAResource calls (start, end). And the
statements are executed through a connection object provided by the
XAConnection.getConnection() method. The XAConnection classs is a
subclass of PooledConenction thus more likely there will be more
transactions executed on the same connection sequentially. This scenario
should cover also the options 1.) and 2.) except some of these call are
performed by the UserTransaction and TransactionManager instances.
Since the XAResource object is accessed thought the call to
XAConnection.getXAResource and the underlying Connection object is
the same I would expect that the work between XAResource.start and
XAResource.end calls have to be done using the same Connection object?
Not the same JDBC Connection object, but the same underlying physical
connection. It's gets confusing in Derby because the physical
connection is a JDBC Connection object, but that is unique to Derby.
If one imagines another C based database system then most likely the
XAResource operations are not going through a JDBC Connection object,
but instead the database's wire protocol directly on a physical
connection (socket).
Why the JDBC Connection object might/should differ?
Thus, if the socket will be closed before the call to XAResource.end
there is no way how to commit a change by the application. How else
should we know that the client application crashed?
Yes, but closing the logical JDBC Connection object by the application
should not be closing the underlying physical connection. Though I
don't know if that's the case here, I'm just trying to provide some
background.
This might make thinks simpler. Actually, I can see two types of
application failures
* The JVM terminates/crashes and everything goes down. It should not be
a problem to handle this since probably also the underlying physical
connection would be closed. In that case the active transactions should
be roll backed even for XA.
* Some unexpected exception is thrown (like NullPointerException) and
the proper disassociation of XA transaction branches from XAResource
objects are not done. It is a more complex problem to handle this. I
have no ideas so far. ;-)
Julo