Mar 21, 2010

How JTA(Java transaction API) works

I am taking a scenario, where an Application thread starts a transaction, perform operation on two different resources( for eg., JDBC, and JMS), and finnaly commits the transaction.

A thread (within Application) wants to start a global transaction, perform operations on several resources, and depending on final status, would commit or rollback, and all within one transaction.

Thread starts the Global Transaction.
TransactionManager.begin( ) is called, a global transaction associates the Transaction Context with the global transaction.

Thread calls TransactionManager.getTransaction( ).
Transaction object is returned. Transaction object represents the Transaction Context associated with the transaction.

Thread associates a resource (assume JDBC resource) with Transaction Object.
TransactionManager.enlistResource( XAResource) would be called. XAResource identifies the resource.
XAResource.start(Xid, flag ) is called. This method is called by Transaction Manager, this method associates the global transaction with the resource.
If the XAResource object represents a resource manager who has not previously seen the global transaction, the TM establishes a different transaction branch ID and ensures that this new resource manager is informed about the transaction completion with proper prepare-commit calls. XID, is the transaction branch identifier. XID is given from TM ro RM. All the RM’s work in support of this global transaction, would be part of only one branch, which has been started right now.

Thread associates another resource (assume JMS resource) with Transaction Object.
Note: for each resource in use by the application thread, the application server invokes the enlistResource( ) method and specifies the XAResource object that identifies the resource in use. The enlistResource( ) request results in the TransactionManager informing the resource manager to start associating the transaction with the work performed through the corresponding resource – by invoking the XAResource.start( ) method.
This Transaction Context represented by Transaction object, already has another XAResource object participating in the transaction, the TransactionManager invokes the XAResource.isSameRM( ) method to determine the specified XAResource represents the same resource manager instance. This returns false, in our case because, the new request is for new JMS resource, and one already registered is JDBC resource.
So, the TM establishes a different branch transaction ID and invokes XAResource.start( ) method, passing the new XID.
The pseudo-code:
public boolean enlistResource(XAResource xares){
// Assume there is already xid1, and a xaRes1 associated with TM.
boolean sameRM = xares.isSameRM(xaRes1);
xares.start(xid1, TMJOIN);
} else {
xid1NewBranch = makeNewBranch(xid1);
xares.start(xidNewBranch, TMNOFLAGS);
Also, Application Server invokes getConnection( ) using Resource Adapter, to make connection, and returns the Connection object reference to the application.

Thread performs some JDBC operations and JMS operations.
Application Thread performs one or more operations on the Connection’s.

Application ends the Transaction, either invoking either commit or rollback.
Application closes the connections, JDBC connection and the JMS connection.
Application Server delist the resource, when notified by the resource adapter about the connection close.
The Transaction manager invokes the XAResource.end to dissociate the transaction from the XAResource.
The application server asks the Transaction Manager to commit the transaction.
Synchronization.beforeCompletion is called by Transaction Manager to notify the Application Server of start of Transaction.
The transaction manager invokes the XAResource.prepare to inform the resource maanger to prepare the transaction work for commit.
The transaction manager invokes the XAResource.commit to commit the transaction.
Synchronization.afterCompletion is called by Transaction Manager to notify the Application Server of start of Transaction.

The resource manager once opened, is kept open until the resource is released(closed) explicitly. When the application ninvokes 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 the connection.
The resource manager initialization is done implicitly by the resource adapter when the resource(connection) is acquired.
There is no xa_open equivalent in the XAResource interface.
Error return values that are caused by the transaction manager's improper handling of the XAResource object are mapped to Java exceptions via the XAException class.
The X/Open XA interface specifies that the transaction manager must initialize a resource manager(xa_open) prior to any xa_ calls.
Knowledge of initializing a resource manager is embedded within the resource adapter that represents the resource manager.

While Coding:

When we are writing an application to use the JTA, we should not be concerned about the details of the distributed transaction management. This is the job of distributed transaction infrastructure - application server, transaction manager, and the resource adapter.
For eg.
While performing JDBC operations, we have application server, transaction manager, and JDBC drivers as distributed transaction infrastructure.
UserTransaction—The javax.transaction.UserTransaction interface provides the application the ability to control transaction boundaries programmatically. The javax.transaction.UserTransaction method starts a global transaction and associates the transaction with the calling thread.
We should not call any method directly on the connection, like: commit(), and rollback() on connection, while performing operation within JTA transaction boundaries.

!!!Any Comments would be really appreciated!!!
© Shift, ShEkUP, Shape, and Surprise | All rights reserved.
Blogger Template Crafted by pipdig