[http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Transaction3.html]
Rolling Back a Container-Managed Transaction
There are two ways to roll back a container-managed transaction. First, if a system exception is thrown, the container will automatically roll back the transaction. Second, by invoking the 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 rollback is not automatic, but may be initiated by a call to setRollbackOnly
. For a description of system and application exceptions, see Handling Exceptions.
The source code for the following example is in the j2eetutorial/examples/src/ejb/bank
directory. To compile the code, go to the j2eetutorial/examples
directory and type ant
bank
. To create the database tables, type ant
create-bank-table
. A sample BankApp.ear
file is in the j2eetutorial/examples/ears
directory.
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:
public 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()); } }
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's 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 SessionSynchronization
interface.