Java Reference
In-Depth Information
logger.log(Level.SEVERE,"An error ocurred processing the order.",ce);
context.setRollbackOnly();
}
...
}
As this snippet shows, calling
setRollbackOnly
on
javax.ejb.EJBContext
marks the transaction for rollback when there's an error processing the credit card. If you
didn't mark the transaction for rollback, then any changes made would actually be commit-
ted. This is an important point to remember—it's your responsibility to tell the container
what to do in the event of an application exception.
The
setRollbackOnly
method on the
EJBContext
can only be used in methods that
have a transaction attribute type of
REQUIRED
,
REQUIRED_NEW
, or
MANDATORY
. If a
transaction hasn't been started, as in the case of
SUPPORTED
or
NEVER
, a
java.lang
.IllegalStateException
will be thrown.
As we stated earlier, when a transaction is marked for rollback, the transaction doesn't
immediately end. The method doesn't return when the transaction is marked for rollback.
Instead, the method will continue as if nothing happened. The
EJBContext
provides a
method that enables you to determine whether a transaction has been marked for rollback:
getRollbackOnly()
. Using this method, you can then decide whether you want to en-
gage in a long-running operation that isn't going to be persisted. You could tweak the code
public void placeSnagItOrder(Item item, Bidder bidder, CreditCard card) {
try {
if(!hasBids(item)) {
creditCardManager.chargeCreditCard(card,item.getInitialPrice());
if(!context.getRollbackOnly()) {
closeBid(item,bidder,item.getInitialPrice());
}
}
Note
The
setRollbackOnly
and
getRollbackOnly
methods can only be invoked in
an EJB using CMT with these transaction attributes:
REQUIRED
,
REQUIRES_NEW
, or
MANDATORY
. Otherwise, the container will throw an
IllegalStateException
.