EJB Transactions

WebLogic supports two flavors of EJB transactions:

Container-managed transactions

Here, the EJB container manages the transaction boundaries. The standard ejb-jar.xml deployment descriptor contains transaction attributes that determine how the EJB container handles transactions across method invocations.

Bean-managed transactions

Here, the EJB implementation is responsible for demarcating transaction boundaries. The bean provider typically uses the transaction methods on the Connection object or the UserTransaction object to ensure all updates occur atomically.

The transaction-type element in the standard ejb-jar.xml descriptor file indicates whether the EJB will manage its own transaction boundaries, or defer all transaction management responsibilities to the EJB container. Both models have their benefits and limitations, and both impose certain restrictions on your EJB code.

6.2.1 Container-Managed Transactions

Container-managed transactions simplify your EJB code because you no longer need to explicitly mark transaction boundaries. You can configure your EJBs so that WebLogic's EJB container automatically creates a new transaction context before delegating the call to the actual EJB method, and commits the transaction just before the method exits. The EJB container rolls back the transaction if a system exception is raised or if the method indicates a rollback should occur. Alternatively, you can indicate that an EJB method must never be executed within a transaction context. Of course, an EJB method need not support transactions at all. All of these options can be configured transparently, without any changes to your EJB code.

Each method call is associated with, at most, one transaction. The J2EE framework does not allow for nested or multiple transactions.

With container-managed transactions, the transactional behavior for your EJBs is determined at deployment time. The standard ejb-jar.xml deployment file lets you specify the transaction attributes for your EJB methods. A transaction attribute determines the scope of a transaction when an EJB method is invoked. It specifies whether an EJB method executes within an existing transaction context. An EJB method can have one of the following transaction attributes:

Never

The method must never execute within an existing transaction context. If the client invokes such a method within a transaction context, the EJB container must throw a RemoteException (EJBException for local client).

NotSupported

The EJB container ensures that the method doesn't execute in a transaction context. If one exists, the container suspends the transaction for the duration of the EJB method, and resumes the transaction once the method exits.

Supports

The method executes with or without an existing transaction context. A new transaction isn't created before the method starts, but if one exists, it will be used, and it may influence the outcome of the transaction.

Required

The method requires a transaction context before it is invoked. If one doesn't exist, a new transaction is created before the method starts.

Mandatory

The method must never execute without a transaction context. If an existing transaction context doesn't exist, the EJB container must throw a TransactionRequiredException.

RequiresNew

A new transaction is created regardless of whether a client transaction context exists. The existing transaction is suspended, the new transaction is created for the duration of the method call, and the existing transaction is resumed once the method terminates.

The following XML fragment shows how you can adjust the transaction settings for the remote EJB methods of the Registration EJB, using the container-transaction element in the ejb-jar.xml deployment descriptor:



 
 
 RegistrationEJB
 Remote
 registerForCourse
 
 ...
 Required
 
 
 
 RegistrationEJB
 Remote
 getCourses
 
 ...
 Supports
 
 ...

The value of the trans-attribute element in the ejb-jar.xml descriptor sets the transaction attribute for EJB methods. In this case, the registerForCourse( ) EJB method must be invoked only from within an existing transaction. If the EJB client doesn't initiate a JTA transaction before invoking the Registration EJB, the EJB container will create one automatically before delegating the call to the method. The getCourses( ) EJB method is configured to support transactions. So, if an EJB client created a transaction before invoking the method, the method will participate in the eventual outcome of the transaction.

In WebLogic Server, if an EJB supports container-managed transactions, the default transaction attribute for the EJB methods is Supports. This means any EJB method that runs within the context of an existing transaction can affect its outcome. Thus, if an EJB method throws a system exception, the EJB container must roll back the existing transaction. However, if an EJB method has a transaction setting of NotSupported or RequiresNew, the EJB container needs to suspend the current transaction before it can delegate the call to the method. In this case, the EJB method will have no effect on the outcome of the original transaction.

An EJB method can cause the EJB container to roll back a transaction in two ways:

  • It can throw a system exception (a RuntimeException or an EJBException).
  • It can invoke the setRollbackOnly( ) method on the EJBContext.

In either case, any transaction-aware updates made by the EJB method will be rolled back. An EJB method that supports container-managed transactions must not interfere explicitly with an existing transaction context. So, within an EJB method:

  • You must not invoke the commit( ), setAutoCommit( ), and rollback( ) methods on the Connection object.
  • You must not call the getUserTransaction( ) method on the EJBContext or use the UserTransaction object.

These operations are allowed only if the EJB needs to explicitly demarcate transaction boundaries i.e., if the EJB methods support bean-managed transactions.

6.2.2 Bean-Managed Transactions

Container-managed transactions have a limitation. A call to an EJB method can be associated with, at most, one transaction at a time. If this constraint makes it difficult for you to write your EJB code, you should consider using bean-managed transactions. Bean-managed transactions allow you to explicitly set the transaction boundaries for your EJB methods. For instance, now you could write an EJB method that updates the database as follows:

begin transaction
...
update table-A
...
if (condition-x) {
 commit transaction
}
else if (condition-y) {
 update table-B
 commit transaction
}
else {
 rollback transaction
 begin transaction
 update table-C
 commit transaction
}
 ...

If the EJB supports bean-managed transactions, you must ensure that the transaction-type element in the standard ejb-jar.xml descriptor file has the value Bean. In this case, the EJB method must use the UserTransaction interface to explicitly demarcate transaction boundaries. The following example shows how an EJB method can perform multiple updates using the UserTransaction interface:

public void doUpdates(int id) {
 try {
 //create a UserTransaction instance using the EJBContext for the bean
 UserTransaction tx = ctx.getUserTransaction( );

 tx.begin( );
 //ds is a reference to an XA-aware data source
 Connection con = ds.getConnection( );
 Statement st = con.createStatement( );
 st.executeUpdate("update tableA set ... where update tableB set ... where docEmphBold">tx.commit( );
 }
 catch (Exception ex) {
 try {
 tx.rollback( );
 throw new EJBException("Tx Failed:" + ex.getMessage( ));
 }
 catch (SystemException ese) {
 throw new EJBException("Tx Rollback Failed:" + ese.getMessage( ));
 }
 }
 finally {
 //release open connections
 }
}

Here, the distributed transaction is bound by the calls to the begin( ) and commit( ) methods on the UserTransaction object. Note that we're using an XA-aware data source to return JDBC connections so that they can participate in the JTA transaction. You also can look in the JNDI tree under java:comp/UserTransaction in order to obtain a reference to the UserTransaction object:

InitialContext ctx = new InitialContext( );
UserTransaction tx = 
 (UserTransaction) ic.lookup("java:comp/UserTransaction");

This is functionally equivalent to calling the getUserTransaction( ) method on the EJBContext.

With bean-managed transactions, your EJB code must explicitly specify when the JDBC updates are committed and when the changes are rolled back. The EJB container remains a silent spectator in this respect because the EJB method itself is entirely responsible for marking the boundaries of the transaction(s). If a transaction context does exist before the invocation of an EJB method that supports bean-managed transactions, the existing transaction is suspended for the duration of the EJB method and resumed once the method exits.

Bean-managed transactions impose certain restrictions on the EJB code as well:

  • Only session and message-driven beans may implement bean-managed transactions. Entity beans may use only container-managed transactions.
  • An EJB that uses bean-managed transactions must never invoke the getRollbackOnly( ) and setRollbackOnly( ) methods on the EJBContext interface. Instead, the EJB should use the getStatus( ) and rollback( ) methods on the UserTransaction interface.
  • An EJB must not attempt to manipulate JDBC transactions from within the EJB method. Thus, you must not invoke the commit( ) or rollback( ) methods on the JDBC Connection object.

Because the EJB container is not involved in the transaction, the EJB method must explicitly commit (or roll back) the transaction before it exits. This holds true for stateless session beans and message-driven beans. A stateful session bean isn't required to do so. An EJB method may initiate a transaction and then complete without committing or rolling back the transaction. In this case, the EJB container is required to maintain the association between the transaction and subsequent method calls until the EJB instance commits (or rolls back) the transaction.

Introduction

Web Applications

Managing the Web Server

Using JNDI and RMI

JDBC

Transactions

J2EE Connectors

JMS

JavaMail

Using EJBs

Using CMP and EJB QL

Packaging and Deployment

Managing Domains

Clustering

Performance, Monitoring, and Tuning

SSL

Security

XML

Web Services

JMX

Logging and Internationalization

SNMP



WebLogic. The Definitive Guide
WebLogic: The Definitive Guide
ISBN: 059600432X
EAN: 2147483647
Year: 2003
Pages: 187

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net