JTA Transactions

 


The Java Transaction API (JTA) allow one to demarcate transactions in a manner that is independent of the transaction manager implementation. The J2EE SDK implements the transaction manager with the Java Transaction Service ("JTS"). But your code doesn't call the JTS methods directly. Instead, it invokes the JTA methods, which then call the lower-level JTS routines.

A JTA transaction is controlled by the J2EE transaction manager. You may want to use a JTA transaction because it can span updates to multiple databases from different vendors. A particular DBMS's transaction manager may not work with heterogeneous databases. However, the J2EE transaction manager does have one limitation--it does not support nested transactions. In other words, it cannot start a transaction for an instance until the previous transaction has ended.

The source code for the following example is in the j2eetutorial/examples/src/ejb/teller directory. To compile the code, go to the j2eetutorial/examples directory and type ant teller. To create the database tables, type ant create-bank-teller. A sample TellerApp.ear file is in the j2eetutorial/examples/ears directory.

To demarcate a JTA transaction, you invoke the begin, commit, and rollback methods of the javax.transaction.UserTransaction interface. The following code, taken from the TellerBean class, demonstrates the UserTransaction methods. The begin and commit invocations delimit the updates to the database. If the updates fail, the code invokes the rollback method and throws an EJBException.

public void withdrawCash(double amount) {

   UserTransaction ut = context.getUserTransaction();

   try {
      ut.begin();
      updateChecking(amount);
      machineBalance -= amount;
      insertMachine(machineBalance);
      ut.commit();
   } catch (Exception ex) {
       try {
          ut.rollback();
       } catch (SystemException syex) {
           throw new EJBException
              ("Rollback failed: " + syex.getMessage());
       }
       throw new EJBException 
          ("Transaction failed: " + ex.getMessage());
    }
}

 

Returning without Committing

In a stateless session bean with bean-managed transactions, a business method must commit or roll back a transaction before returning. However, a stateful session bean does not have this restriction.

In a stateful session bean with a JTA transaction, the association between the bean instance and the transaction is retained across multiple client calls. Even if each business method called by the client opens and closes the database connection, the association is retained until the instance completes the transaction.

In a stateful session bean with a JDBC transaction, the JDBC connection retains the association between the bean instance and the transaction across multiple calls. If the connection is closed, the association is not retained.

 

Methods Not Allowed in Bean-Managed Transactions

Do not invoke the getRollbackOnly and setRollbackOnly methods of the EJBContext interface in bean-managed transactions. These methods should be used only in container-managed transactions. For bean-managed transactions, invoke the getStatus and rollback methods of the UserTransaction interface.