Exploring Transactions Across the J2EE Tiers

Distributed transactions in J2EE applications are supported by the EJB container (application server). Both the Web tier, and the EJB tier can provide distributed transaction capability, which means that they can access the UserTransaction interface. Applets and J2EE client applications are not required to provide distributed transaction support (and doing so is not recommended). We strongly recommend using distributed transactions through the EJB tier. As explained on Day 9, placing all your JDBC calls in EJBs ensures a high degree of server application portability. This relieves application developers from having to manage transaction control with explicit JDBC calls or JMS messages.

In the Web tier, a client component (such as a JSP or servlet) can obtain a UserTransaction using JNDI Context, as explained in the previous section. Transaction demarcation should start and complete in the servlet's service() method.

Caution

Few architects encourage the use of distributed transactions in the Web tier through the use of a servlet or a JSP, which are not transactional by design. On the other hand, EJBs are transactional components that can be managed by the EJB container or by the bean code itself.


Learning Bean-Managed Transactions

Only session beans and message-driven beans can manage transactions programmatically. All transaction demarcations are managed by the bean's code. Session beans and MDBs can establish a UserTransaction context from EJBContext. The bean then uses the context in other transactional demarcation.

Note

EJBs establish transaction context from EJBContext, and not through looking up the JNDI service, as in the case of a JSP or servlet. The container passes the bean's transaction context secretly to the bean's context.

public class UserManagerBean implements SessionBean {
   SessionContext ctx = null;
   public void setSessionContext(SessionContext ctx) {
     this.ctx = ctx;}
   // Implement other methods such as ejbCreate, ejbRemove,
   ...
   public void connectUserManager(){
     // Create a UserTransaction context from the EJB context
     UserTransaction utx = ctx.getUserTranssaction();
     utx.begin();
     // Access multiple resources as one unit-of-work
     utx.commit();
     ...
   }
// other methods of the class
}

Only session beans and message-driven beans can use bean-managed transaction demarcation. Entity beans must always use a container-managed transaction demarcation.


To control the bean access performance, the transaction isolation level can be set programmatically using the setTransactionIsolation() method on the Connection object. Full coverage of bean-managed transactions is in Day 17.

Container-Managed Transactions

In a container-managed transaction, the EJB container manages the transaction demarcation for each method of the bean. Transaction behavior is described in the bean's deployment descriptor. Transaction attributes determine how the EJB container handles transactions with each bean's method invocation. Each method can be associated with only a single transaction. A transaction begins just before the method starts, and commits just before it exits. Not all methods of the bean are associated with transactions, only those specified in the bean's deployment descriptor by transaction attributes. The following section introduces the transaction attributes that are vital in configuring the bean's methods participating in a container-managed transaction.

Transaction Attributes

For a bean participating in a container-managed transaction, transaction attributes are set in the bean's deployment descriptor. It is possible to set a transaction attribute for the whole bean or for only individual methods. A transaction attribute must be specified for the methods in the remote interface of a session bean, and for the methods in the home and remote interfaces of an entity bean. Transactional behavior of the bean can be controlled declaratively by changing the transaction attributes in the deployment descriptor. Table 16.3 summarizes the transaction attributes of a container-managed transaction.

Table 16.3. Container-Managed Transaction Attributes
AttributeDescription
NotSupportedThe bean does not support transactions. Transactions will not be propagated through the bean. If the client is associated with a transaction context, the container will suspend the transaction before invoking the bean's method. After the method completes, the container resumes the suspended transaction association.
SupportsIf the client is associated with a transaction context, it will be propagated through the bean's method. If the client is not associated with a transaction context, it will be suspended.
RequiredThe bean will always be part of a JTA transaction. If the client is associated with a JTA transaction, the context will be propagated to the bean's method. If the client is not associated with a transaction, the container begins a new transaction, and commits when the method returns.
RequiresNewThe EJB container always begins a new transaction before invoking the bean's method, and commits upon the method's return. If the calling client is associated with a transaction context, the container suspends the transaction with the current thread before starting the new transaction. When the method and the transaction complete, the container resumes the suspended transaction.
MandatoryThe calling client must be associated with a transaction; otherwise, invoking the bean's method will fail, throwing a TransactionRequiredException.
NeverThe calling client must not be associated with a transaction; otherwise, invoking the bean's method will fail, throwing a RemoteException.

The following is an example of a deployment descriptor of a stateful session bean with a container-managed transaction demarcation:

<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC
'-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN'
'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
<ejb-jar>
  <enterprise-beans>
    <session>
      <ejb-name>EnrollmentCart</ejb-name>
      <home>EnrollmentCartHome</home>
      <remote>EnrollmentCart</remote>
      <ejb-class>EnrollmentCartBean</ejb-class>
      <session-type>Stateful</session-type>
      <transaction-type>Container</transaction-type>
    </session>
  </enterprise-beans>
  <assembly-descriptor>
    <container-transaction>
      <method>
								<ejb-name>EnrollmentCart</ejb-name>
								<method-intf>Remote</method-intf>
								<method-name>getCourses</method-name>
								<method-params/>
								</method>
								<trans-attribute>Required</trans-attribute>
    </container-transaction>
  </assembly-descriptor>
</ejb-jar>

Notice that only the getCourses() method is specified with the transaction attribute Required.

It's always recommended to use container-managed transactions in a J2EE application if possible. Container-managed transactions are easy to implement. They keep your applications more portable and flexible in deployment. Container-managed transactions will be covered in more detail in Day 18.

Note

It is also recommended that an EJB component always access a data source under the scope of a transaction because this provides some guarantee of the integrity and consistency of the data.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.186.143