Prev | Next | J2EETM Developer's Guide
Transactions |
Typically, the container begins a transaction immediately before an enterprise bean method starts. It commits the transaction just before the method exits. Each method can be associated with a single transaction. Nested or multiple transactions are not allowed within a method.
Container-managed transactions do not require all methods to be associated with transactions. When deploying a bean, you specify which of the bean's methods are associated with transactions by setting the transaction attributes.
The Required attribute will work for most transactions. Therefore, you may want to use it as a default, at least in the early phases of development. Because transaction attributes are declarative, you can easily change them at a later time.
You should use the RequiresNew attribute when you want to ensure that the method always runs within a new transaction.
TransactionRequiredException
.
Use the Mandatory attribute if the enterprise bean's method must use the transaction of the client.
If the client is not associated with a transaction, the container does not start a new transaction before running the method.
Use the NotSupported attribute when you want to ensure that the method will never run within a transaction generated by the container.
Because the transactional behavior of the method may vary, you should use the Supports attribute with caution.
RemoteException
. If the client is not associated with a transaction, the container does not start a new transaction before running the method.
In the last column, the word "none" means that the business method does not execute within a transaction controlled by the container. However, the database calls in such a business method might be controlled by the transaction manager of the DBMS.
You can specify the transaction attributes for the entire enterprise bean or for individual methods. If you've specified one attribute for a method and another for the bean, the attribute for the method takes precedence. When specifying attributes for individual methods, the requirements for session and entity beans vary. Session beans need the attributes defined for business methods, but do not allow them for the create
methods. Entity beans require transaction attributes for the business, create
, remove
, and finder methods.
setRollbackOnly
method of the EJBContext
interface, the bean method instructs the container to roll back the transaction. If the bean throws an application exception, the roll back is not automatic, but may be initiated by a call to setRollbackOnly
. (See the section "Handling Exceptions" for a description of system and application exceptions.)
The transferToSaving
method of the BankEJB
example illustrates the setRollbackOnly
method. If a negative checking balance occurs, transferToSaving
invokes setRollBackOnly
and throws an application exception (InsufficientBalanceException
). The updateChecking
and updateSaving
methods update database tables. If the updates fail, these methods throw a SQLException
and the transferToSaving
method throws an EJBException
. Because the EJBException
is a system exception, it causes the container to automatically roll back the transaction. Here is the code for the transferToSaving
method:
When the container rolls back a transaction, it always undoes the changes to data made by SQL calls within the transaction. However, only in entity beans will the container undo changes made to instance variables. (It does so by automatically invoking the entity bean'spublic void transferToSaving(double amount) throws InsufficientBalanceException { checkingBalance -= amount; savingBalance += amount; try { updateChecking(checkingBalance); if (checkingBalance < 0.00) { context.setRollbackOnly(); throw new InsufficientBalanceException(); } updateSaving(savingBalance); } catch (SQLException ex) { throw new EJBException ("Transaction failed due to SQLException: " + ex.getMessage()); } }
ejbLoad
method, which loads the instance variables from the database.) When a rollback occurs, a session bean must explicitly reset any instance variables changed within the transaction. The easiest way to reset a session bean's instance variables is by implementing the SessionSynchonization
interface.
SessionSynchonization
interface, which is optional, allows you to synchronize the instance variables with their corresponding values in the database. The container invokes the SessionSynchonization
methods-- afterBegin
, beforeCompletion
, and afterCompletion
-- at each of the main stages of a transaction.
The afterBegin
method informs the instance that a new transaction has begun. The container invokes afterBegin
immediately before it invokes the business method. The afterBegin
method is a good place to load the instance variables from the database. The BankEJB class, for example, loads the
checkingBalance
and savingBalance
variables in the afterBegin
method:
The container invokes thepublic void afterBegin() { System.out.println("afterBegin()"); try { checkingBalance = selectChecking(); savingBalance = selectSaving(); } catch (SQLException ex) { throw new EJBException("afterBegin Exception: " + ex.getMessage()); } }
beforeCompletion
method after the business method has finished, but just before the transaction commits. The beforeCompletion
method is the last opportunity for the session bean to roll back the transaction (by calling setRollbackOnly
). If it hasn't already updated the database with the values of the instance variables, the session bean may do so in the beforeCompletion
method.
The afterCompletion
method indicates that the transaction has completed. It has a single boolean parameter, whose value is true if the transaction was committed and false if it was rolled back. If a rollback occurred, the session bean can refresh its instance variables from the database in the afterCompletion
method:
public void afterCompletion(boolean committed) { System.out.println("afterCompletion: " + committed); if (committed == false) { try { checkingBalance = selectChecking(); savingBalance = selectSaving(); } catch (SQLException ex) { throw new EJBException("afterCompletion SQLException: " + ex.getMessage()); } } }
commit
, setAutoCommit
, and rollback
methods of java.sql.Connection
getUserTransaction
method of javax.ejb.EJBContext
javax.transaction.UserTransaction