Transactional Stateful Session Beans

Session beans can interact directly with the database as easily as they can manage the taskflow of other enterprise beans. The ProcessPayment EJB, for example, makes inserts into the PAYMENT table when the byCredit( ) method is invoked, and the TravelAgent EJB queries the database directly when the listAvailableCabins( ) method is invoked. Stateless session beans such as the ProcessPayment EJB have no conversational state, so each method invocation must make changes to the database immediately. With stateful session beans, however, we may not want to make changes to the database until the transaction is complete. Remember, a stateful session bean can be one of many participants in a transaction, so it may be advisable to postpone database updates until the entire transaction is committed or to avoid updates if it is rolled back.

There are several different scenarios in which a stateful session bean might cache changes before applying them to the database. For example, think of a shopping cart implemented by a stateful session bean that accumulates several items for purchase. If the stateful bean implements SessionSynchronization, it can cache the items and write them to the database only when the transaction is complete.

The javax.ejb.SessionSynchronization interface allows a session bean to receive additional notification of the session’s involvement in transactions. The addition of these transaction callback methods by the SessionSynchronization interface expands the EJB’s awareness of its life cycle to include a new state, the Transactional Method-Ready state. This third state, although not discussed in Chapter 11, is always a part of the life cycle of a transactional stateful session bean. Implementing the SessionSynchronization interface simply makes it visible to the EJB. Figure 16-11 shows the stateful session bean with the additional state.

Life cycle of a stateful session bean

Figure 16-11. Life cycle of a stateful session bean

The SessionSynchronization interface is defined:

package javax.ejb;

public interface javax.ejb.SessionSynchronization {
    public abstract void afterBegin( ) throws RemoteException;
    public abstract void beforeCompletion( ) throws RemoteException;
    public abstract void afterCompletion(boolean committed) throws RemoteException;
}

When a method of the SessionSynchronization bean is invoked outside of a transaction scope, the method executes in the Method-Ready state, as discussed in Chapter 11. However, when a method is invoked within a transaction scope (or creates a new transaction), the EJB moves into the Transactional Method-Ready state.

The Transactional Method-Ready State

The SessionSynchronization methods are called in the Transactional Method-Ready state.

Transitioning into the Transactional Method-Ready state

When a transactional method is invoked on a SessionSynchronization bean, the stateful bean becomes part of the transaction, causing the afterBegin( ) callback method defined in the SessionSynchronization interface to be invoked. This method should take care of reading any data from the database and storing the data in the bean’s instance fields. The afterBegin( ) method is called before the EJB object delegates the business-method invocation to the EJB instance.

Life in the Transactional Method-Ready state

When the afterBegin( ) callback method completes, the business method originally invoked by the client is executed on the EJB instance. Any subsequent business methods invoked within the same transaction will be delegated directly to the EJB instance.

Once a stateful session bean is a part of a transaction—whether it implements SessionSynchronization or not—it cannot be accessed by any other transactional context. This is true regardless of whether the client tries to access the EJB with a different context or the EJB’s own method creates a new context. If, for example, a method with a transaction attribute of RequiresNew is invoked, the new transactional context causes an error to be thrown. Since the NotSupported and Never attributes specify a different transactional context (no context), invoking a method with these attributes also causes an error. A stateful session bean cannot be removed while it is involved in a transaction. This means that invoking ejbRemove( ) while the SessionSynchronization bean is in the middle of a transaction will cause an error to be thrown.

At some point, the transaction in which the SessionSynchronization bean has been enrolled will come to an end. If the transaction is committed, the SessionSynchronization bean will be notified through its beforeCompletion( ) method. At this time, the EJB should write its cached data to the database. If the transaction is rolled back, the beforeCompletion( ) method will not be invoked, avoiding the pointless effort of writing changes that won’t be committed to the database.

The afterCompletion( ) method is always invoked, whether the transaction ended successfully with a commit or unsuccessfully with a rollback. If the transaction was a success—which means that beforeCompletion( ) was invoked—the committed parameter of the afterCompletion( ) method will be true. If the transaction was unsuccessful, committed will be false.

It may be desirable to reset the stateful session bean’s instance variables to some initial state if the afterCompletion( ) method indicates that the transaction was rolled back.

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

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