J2EE Transaction Frameworks, Part 3
by Dibyendu Baksi
06/06/2001
The previous two parts of this series discussed the fundamentals of
transaction processing in a distributed, component-based environment,
as well as the way explicit transaction management is done for the
most common J2EE configurations. This part continues the discussion by
describing declarative transaction management of session, entity, and
message-driven beans. I also describe guidelines for implicit or
explicit global transaction management. Finally, local transaction
management is described along with common pitfalls and their
solutions.
Container-managed transaction
The EJB container is responsible for managing transaction
boundaries in the case of declarative transaction management. The way
the container manages transactions for a method in an EJB is
determined by its transaction attribute. The benefits of using
container-managed transactions are listed below.
The ability to specify transactional behavior of an
enterprise bean frees the application component provider from writing
transaction specification logic in the code.
Since the container automatically handles transaction
demarcation at run time, it's more reliable.
Since transactions are viewed as a property of the overall
application, it's easier an application assembler who understands the
application to customize the transaction attributes in the deployment
descriptor to change the application behavior.
Even in container-managed demarcation, an EJB has some control over
the transaction. For example, an enterprise bean can choose to roll
back a transaction started by the container using the method
setRollbackOnly on the SessionContext or
EntityContext object.
Transaction Attributes
A transaction attribute is a value associated with a method of a
session, or an entity bean's remote or home interface, or with the
onMessage method of a message-driven bean. It specifies
how the container must manage transactions for a method when a client
invokes it via the home or remote interface or when the method gets
invoked as the result of the arrival of a JMS message. In the majority
of cases, all methods of an enterprise bean will have the same
transaction attribute. However, it is possible to have different
attributes for different methods in the same EJB for special purposes,
like when an EJB may have methods that don't need to be
transactional.
The transaction attribute must be specified for the following
methods:
For a session bean, the transaction attributes must be specified
for the methods defined in the bean's remote interface and all the
direct and indirect superinterfaces of the remote interface, excluding
the methods of the javax.ejb.EJBObject
interface. Transaction attributes must not be specified for the
methods of a session bean's home interface.
- For an entity bean, the transaction attributes must be
specified for the methods defined in the bean's remote interface and
all the direct and indirect superinterfaces of the remote interface,
excluding the
getEJBHome, getHandl,
getPrimaryKey, and isIdentical methods; and
for the methods defined in the bean's home interface and all the
direct and indirect superinterfaces of the home interface, excluding
the getEJBMetaData and getHomeHandle
methods.
- For a message-driven bean, the transaction attribute must be
specified for the bean's
onMessage method.
The description for each type of transaction attribute follows. In
the explanations of the different attributes, calling client and
parent are meant to be the same as is the called method of the server
EJB and child.
Required
The container always ensures that the method of the EJB is invoked
with a JTA transaction. If the calling client is associated with a JTA
transaction, the enterprise bean method will be invoked in the same
transaction context. However, if a client is not associated with a
transaction, the container will automatically begin a new transaction
and try to commit the transaction when the method completes.

Figure 1 Transaction propagation in Required
|
Required in message driven beans:
The container invokes a message driven bean method with its
transaction attribute set to Required with a valid
transaction context. Since there is no client transaction context
available for a message-driven bean, the container automatically
starts a new transaction before the dequeuing of the JMS message which
is before the invocation of the onMessage method. The
container automatically enlists the resource manager associated with
the arriving message and all the resource managers accessed by the
onMessage method with the transaction. If the
onMessage method invokes other enterprise beans, the
container propagates the transaction context with the
invocation. Finally, it attempts to commit the transaction when the
onMessage method has completed. In case the
onMessage method does not successfully complete, the
transaction is rolled back by the container and typical JMS message
redelivery semantics apply.
This is the only scenario in which the interface to the JMS topic
or queue is involved in the EJB transaction. For EJBs with the
Required attribute, the JMS server will be enlisted as an
XAResource. If the JMS server provider does not support XA
transactions, the commit or rollback on the JMS session will typically
be synchronized with the result of the container's global transaction.
In this case, the container will not be able to involve the JMS server
in the 2PC process used in managing distributed transactions. A
rollback on the JMS session will alert the JMS server that the message
should be delivered.
Handling of setRollbackOnly() method:
The container must handle the
EJBContext.setRollbackOnly() method invoked from a
onMessage method executing with the Required
transaction attribute by making sure that the transaction will never
commit. Typically the transaction manager is instructed by the
container to mark the transaction for rollback. When the method
invocation completes, the container must roll back rather than commit
the transaction. The Container must throw and log the
java.lang.IllegalStateException if the
EJBContext.setRollbackOnly() method is invoked from an
onMessage method executing with the
NotSupported transaction attribute
Handling of getRollbackOnly() method:
The container must handle the
EJBContext.getRollbackOnly() method invoked from an
onMessage method by throwing and logging the
java.lang.IllegalStateException if the
EJBContext.getRollbackOnly() method is invoked from an
onMessage method executing with the
NotSupported transaction attribute
Handling of getUserTransaction() method:
If an instance of a message-driven bean with container-managed
transaction demarcation attempts to invoke the
getUserTransaction() method of the
EJBContext interface, the container must throw and log
the java.lang.IllegalStateException.