Using Local or Global Transactions in BMT

When coding a bean-managed transaction, you need to decide whether to use Java Database Connectivity (JDBC) for local transaction or the Java Transaction API (JTA) for distributed and global transactions. On Day 9, “Using JDBC to Connect to a Database,” you learned how to use JDBC transactions, and on Day 16, “Understanding J2EE Transactions,” you learned how to use JTA transactions. You also learned that JTA is the approach recommended by the J2EE platform and should be used whenever possible. In the next sections, we'll review both transaction management mechanisms, and discuss the rationale behind using either mechanism for BMT.

Using JDBC Transactions in BMT

A JDBC transaction is controlled by the resource manager of the underlying DBMS. With JDBC, you invoke the setAutoCommit(false) method of the javax.sql.Connection interface before you start demarcating a transaction with the commit() and rollback() methods. The beginning of the transaction is implicit; a new transaction starts by the first SQL call following the most recent getConnection(), commit(), or rollback() method.

The isolation level describes the degree to which a transaction's access to a resource manager is isolated from the access to the resource manager by other concurrently executing transactions. The API for managing an isolation level is resource manager–specific. That means the EJB architecture does not define an API for managing the isolation level. For session beans and message-driven beans with bean-managed transaction demarcation, the EJB developer can specify the desirable isolation level programmatically in the enterprise bean's methods by using the resource manager–specific API. For example, you can use the setTransactionIsolation(int iLevel) method of the Connection interface to set the appropriate isolation level for database access.

The following code illustrates a session bean that uses the Connection interface's methods to demarcate bean-managed transactions:

public class MySessionBeanA implements SessionBean {
...
  public void businessMethodA(...){
    // Using JDBC to perform local transaction on connection
    conn.setAutoCommit(false);
    // Set transaction isolation level on the Connection object
    conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
    // JDBC transaction begins implicitly here...
    Statement stmt = conn.createStatement();
    try {
      ...
      conn.commit();
    } catch (SQLException ex) {
       conn.rollback();
       stmt.close();
    }
  }
...
}

The method starts by invoking setAutoCommit() on the Connection object. This invocation tells the DBMS not to automatically commit every SQL statement. Next, the same method calls routines that update the database tables. If the updates succeed, the transaction is committed. But if an exception is thrown, the transaction is rolled back.

You might want to use JDBC transactions when wrapping legacy code inside a session bean.

Using JTA Transactions in BMT

JTA implements global transactions for J2EE components and applications in which all resource managers are registered with the global transaction manager that handles the transactions. For a global transaction, the enterprise bean never makes calls directly on a database connection or a JMS session. In JTA, transactions are demarcated by begin(), commit(), and rollback() methods of the UserTransaction interface.

Caution

While an EJB instance is in a transaction, the instance must not attempt to use the resource manager–specific transaction demarcation API. That means it must not invoke the commit() or rollback() method on the java.sql.Connection interface or on the javax.jms.Session interface.


The available methods of the UserTransaction interface support demarcation of a transaction, setting transaction timeout, and rolling back a transaction. A client program with BMT can use explicit transaction demarcation to perform, throughout EJB, atomic updates across multiple databases connected to multiple EJB containers, (see Day 16). Table 18.1 lists a summary of the methods of the UserTransaction interface used by BMT components to demarcate transaction boundaries.

Table 18.1. Summary of UserTransaction Methods
MethodDescription
void begin()Creates a new transaction and associates it with the current thread.
void commit()Completes the transaction associated with the current thread.
int getStatus()Obtains the status of the transaction associated with the current thread. See Table 18.2 for the status constants and their meanings.
void rollback()Rolls back the transaction associated with the current thread.
void setRollbackOnly()Modifies the transaction associated with the current thread such that the only possible outcome of the transaction is to roll back the transaction.
void setTransactionTimeout(int seconds)Modifies the timeout value associated with transactions started by subsequent invocations of the begin method.

You should avoid calling the getRollbackOnly() and setRollbackOnly() methods of the EJBContext interface for BMT. An EJB with BMT has no need to use these methods because it can obtain the status of a transaction by using the getStatus() method, and also can roll back a transaction using the rollback() method of the UserTransaction interface if required.

Caution

As you learned on Day 17, the methods getRollbackOnly() and setRollbackOnly() of the EJBContext interface are for the use of EJB with CMT only.


When an application needs to know about the status of its transaction, it can query the transaction manager by invoking the getStatus() method on the UserTransaction object. A summary of the JTA transaction statuses is listed in Table 18.2, where each status constant is represented as static int.

Table 18.2. Summary of JTA Transaction Status
Status ConstantMeaning
STATUS_ACTIVETransaction is in the active state.
STATUS_COMMITTEDTransaction has been committed.
STATUS_COMMITTINGTransaction is in the process of committing.
STATUS_MARKED_ROLLBACKTransaction has been marked for rollback. This could be a result of using the setRollbackOnly() method.
STATUS_NO_TRANSACTIONNo transaction is currently associated with the target instance.
STATUS_PREPAREDTransaction has been prepared.
STATUS_PREPARINGTransaction is in the process of preparing.
STATUS_ROLLEDBACKTransaction manager determined that the transaction state is a rollback.
STATUS_ROLLING_BACKTransaction is in the process of rolling back.
STATUS_UNKNOWNCurrent status of transaction cannot be determined.

The following example demonstrates the use of a JTA transaction in an EJB with bean-managed transaction demarcation:

SessionContext ctx;
...
// Using JTA for distributed transaction.
public void businessMethodB(){
   try {
      // Establish a UserTransaction context from EJBContext
      UserTransaction ut = ctx.getUserTransaction();
      // Begin the distributed transaction
      ut.begin();
      ...
      ut.commit();
   } catch(Exception e) {
      ut.rollback();
   }
...

In the preceding example, the transaction context ut is obtained from the EJBContext (in this case, the SessionContext) because the EJB container maintains such context for transaction propagation across components and applications.

Setting Transaction Timeouts with BMT

The transaction timeout is a useful mechanism of specifying an expected period for a transaction to execute. This gives application code more control over managing transactions. EJB developers specify the timeout period for transactions in EJB with BMT by calling the setTransactionTimeout() method of the UserTransaction interface. If the duration of a transaction exceeds the specified timeout setting, the transaction manager rolls back the transaction automatically. Here is an example of setting the transaction timeout to 30 seconds:

// obtain user transaction context
   ut = ejbContext.getUserTransaction();
// set transaction timeout before beginning a transaction
   ut.setTransactionTimeout(30);
// start a transaction
   ut.begin();
   ...

Note

You must set the timeout before you begin the transaction. Setting a timeout does not affect a transaction that has already started.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.119.81