Transaction management under J2EE 1.2
Explore your options for managing transactions
By Sanjay Mahapatra, JavaWorld.com, 07/14/00
Page 2 of 3
The J2EE platform supports two transaction-management paradigms: declarative transaction demarcation and programmatic transaction demarcation.
Declarative transaction demarcation
Declarative transaction management refers to a non-programmatic demarcation of transaction boundaries, achieved by specifying
within the deployment descriptor the transaction attributes for the various methods of the container-managed EJB component.
This is a flexible and preferable approach that facilitates changes in the application's transactional characteristics without
modifying any code. Entity EJB components must use this container-managed transaction demarcation.
What is a transaction attribute?
A transaction attribute supports declarative transaction demarcation and conveys to the container the intended transactional
behavior of the associated EJB component's method. Six transactional attributes are possible for container-managed transaction
demarcation:
- Required: A method with this transactional attribute must be executed within a JTA transaction; depending on the circumstances, a new
transaction context may or may not be created. If the calling component is already associated with a JTA transaction, the
container will invoke the method in the context of said transaction. If no transaction is associated with the calling component,
the container will automatically create a new transaction context and attempt to commit the transaction when the method completes.
- RequiresNew: A method with this transactional attribute must be executed in the context of a new transaction. If the calling component
is already associated with a transaction context, that transaction is suspended, a new transaction context is created, and
the method is executed in the context of the new transaction, after whose completion the calling component's transaction is
resumed.
- NotSupported: A method with this transactional attribute is not intended to be part of a transaction. If the calling component is already
associated with a transaction context, the container suspends that transaction, invokes the method unassociated with a transaction,
and upon completion of the method, resumes the calling component's transaction.
- Supports: A method with this transactional attribute supports the calling component's transactional situation. If the calling component
does not have any transactional context, the container will execute the method as if its transaction attribute was
NotSupported. If the calling component is already associated with a transactional context, the container will execute the method as if
its transactional attribute was Required.
- Mandatory: A method with this transactional attribute must only be called from the calling component's transaction context. Otherwise,
the container will throw a
javax.transaction.TransactionRequiredException.
- Never: A method with this transactional attribute should never be called from a calling component's transaction context. Otherwise,
the container will throw a
java.rmi.RemoteException.
Methods within the same EJB component may have different transactional attributes for optimization reasons, since all methods
may not need to be transactional. The isolation level of entity EJB components with container-managed persistence is constant,
as the DBMS default cannot be changed. The default isolation level for most relational database systems is usually ReadCommitted.
Programmatic transaction demarcation
Programmatic transaction demarcation is the hard coding of transaction management within the application code. Programmatic
transaction demarcation is a viable option for session EJBs, servlets, and JSP components. A programmatic transaction may
be either a JDBC or JTA transaction. For container-managed session EJBs, it is possible -- though not in the least recommended
-- to mix JDBC and JTA transactions.
JDBC transactions
JDBC transactions are controlled by the DBMS's transaction manager. The JDBC Connection -- the implementation of the
java.sql.Connection interface - supports transaction demarcation. JDBC connections have their auto-commit flag turned on by default, resulting
in the commitment of individual SQL statements immediately upon execution. However, the auto-commit flag can be programmatically
changed by calling the
setAutoCommit() method false with the argument. Afterward, SQL statements may be serialized to form a transaction, followed by a programmatic
commit() or
rollback(). Thus, JDBC transactions are delimited with the commit or rollback. A particular DBMS's transaction manager may not work
with heterogeneous databases. JDBC drivers that support distributed transactions provide implementations for
javax.transaction.xa.XAResource and two new interfaces of JDBC 2.0,
javax.sql.XAConnection and
javax.sql.XADataSource.
JTA transactions
JTA transactions are controlled and coordinated by the J2EE transaction manager. JTA transactions are available to all the
J2EE components -- servlets, JSPs, and EJBs -- for programmatic transaction demarcation. Unlike JDBC transactions, in JTA
transactions the transaction context propagates across the various components without additional programming effort. In J2EE
server products, which support the distributed two-phase commit protocol, a JTA transaction can span updates to multiple diverse
databases with minimal coding effort. However, JTA supports only flat transactions, which have no nested (child) transactions.
The javax.transaction.UserTransaction interface defines methods that allow applications to define transaction boundaries and explicitly manage transactions. The
UserTransaction implementation also provides the application components -- servlets, JSPs, EJBs (with bean-managed transactions) -- with
the ability to control transaction boundaries programmatically. EJB components can access UserTransaction via EJBContext using the getUserTransaction() method. The methods specified in the UserTransaction interface include begin(), commit(), getStatus(), rollback(), setRollbackOnly(), and setTransactionTimeout(int seconds). The J2EE server provides the object that implements the javax.transaction.UserTransaction interface and makes it available via JNDI lookup. The isolation level of session EJB components and entity EJB components
that use bean-managed persistence may be programmatically changed using the setTransactionIsolation() method; however, changing the isolation level in mid-transaction is not recommended.