Reviewing Transaction Attributes with CMT

Transaction attributes were briefly covered on Day 16. Here you'll learn more about using transaction attributes to control the scope of a container-managed transaction. When methodA of EJB1 invokes methodB of EJB2 (see Figure 17.2), the scope of the transaction depends on the transaction attribute setting of methodB in the deployment descriptor of EJB2.

Figure 17.2. Transaction scope.


Table 17.1 summarizes the effects of the transaction attribute of methodB on the scope of the originated transaction. In this table, both T1 and T2 are transactions that are controlled by the container. The T1 transaction is associated with EJB1, which calls methodB in EJB2. The container starts the T2 transaction just before methodB executes. Depending on the transaction attribute setting of methodB, the container will propagate the context of transaction T1's scope, or start a new T2 transaction. Notice that in some cases, methodB does not execute within a transaction controlled by the container, as specified by N/A in the table. EJB components inherit the transaction of the caller even if the caller is a distributed client. The EJB container propagates the transaction context across EJB components and J2EE-compliant application servers.

Table 17.1. Transaction Attributes and Scope
Transaction AttributeEJB1.methodEJB2.methodB
RequiredNoneNew transaction: T2
 T1T1
RequiresNewN/ANew transaction: T2
 T1New transaction: T2
MandatoryN/ATransactionRequiredException
 T1T1
NotSupportedN/AN/A
 T1N/A
SupportsN/AN/A
 T1T1
NeverN/AN/A
 T1TransactionRequiredException

As you can see in Table 17.1, based on the transaction attribute settings, the EJB container takes an appropriate action. For example, if the setting is Required, the EJB container invokes the method within the existing transaction context (T1). But if the client methodA calls without a transaction context, the EJB container begins a new transaction (T2) before executing methodB. In another example, if the transaction attribute is Mandatory, the EJB container invokes methodB within the existing transaction context (T1). But if the client calls without a transaction context, the EJB container throws the TransactionRequiredException exception of the UserTransaction interface.

Setting Transaction Attributes

Transaction attributes control the method behavior of an EJB, and are stored in the standard deployment descriptor ejb-jar.xml. They can be changed during several phases of J2EE application development, application assembly, and deployment. As an EJB developer, it is your responsibility to specify these attributes when creating the bean. Only an application developer who is assembling components into larger applications should modify the attributes. The J2EE deployer is not expected to modify these attributes.

You can specify the transaction attributes for the entire EJB methods or just for individual methods. If you've specified one attribute for a method and another for the entire EJB as a default, the attribute for the method takes precedence. When specifying attributes for individual methods, the requirements for session and entity beans vary. Session beans need the attributes defined for business methods, but do not allow them for the create methods. Entity beans require transaction attributes for the business, create, remove, and finder methods.

The assembler uses the <container-transaction> element to define the transaction attributes for the methods of session and entity beans' home and component interfaces, and for the onMessage() methods of message-driven beans. Each <container-transaction> element consists of a list of one or more <method> elements and the <trans-attribute> element. The <container-transaction> element specifies that all the listed methods must be assigned the specified transaction attribute value. It is required that all the methods specified in a single <container-transaction> element be methods of the same EJB. The <method> element uses the <ejb-name>, <method-name>, and <method-params> elements to denote one or more methods of an EJB's home and component interfaces. In the following sections, you'll learn three different styles of how to compose the <method> element to specify a transaction attribute.

Tip

Specifying container-managed transactions with the Required transaction attribute is the easiest way to handle transaction management in the application, and works in most cases.


Setting Transaction Attributes for the Entire EJB

This style is used to specify a default value of the transaction attribute for all the methods of the EJB. The <method-name> tag is assigned the value * (asterisk) to indicate that all methods have the transaction attribute Required:

<ejb-jar>
   ...
   <assembly-descriptor>
     ...
     <container-transaction>
      <method>
        <ejb-name> myEJB </ejb-name>
        <method-name> * </method-name>
        <trans-attribute>Required</trans-attribute>
     </method>
     ...
   </assembly-descriptor>
   ...
</ejb-jar>

Setting a Transaction Attribute for a Specific Method

This style is used for referring to a specific method of a home or component interface of the specified EJB:

<ejb-jar>
   ...
   <assembly-descriptor>
     ...
     <container-transaction>
      <method>
        <ejb-name> myEJB </ejb-name>
        <method-name> methodA </method-name>
        <trans-attribute>Supports</trans-attribute>
     </method>
     ...
   </assembly-descriptor>
   ...
</ejb-jar>

Setting a Transaction Attribute for an Overloaded Method

If there are multiple overloaded methods (that is, the same method name with different parameter types), this style uses the <method-params> tag to differentiate which method to set:

<ejb-jar>
   ...
   <assembly-descriptor>
     ...
     <container-transaction>
      <method>
        <ejb-name> myEJB </ejb-name>
        <method-name> methodA </method-name>
								<method-params>
								<method-param> java.lang.Object </method-param>
								...
								<method-param> java.lang.String </method-param>
								</method-params>
        <trans-attribute>RequiredNew</trans-attribute>
     </method>
     ...
   </assembly-descriptor>
   ...
</ejb-jar>

Caution

In specifying the data type in the <method-param> tag, use the fully qualified class name; for example, java.lang.String.


The optional <method-intf> element can be used to differentiate between methods with the same name and signature that are multiply defined across the component and/or home interfaces:

<ejb-jar>
   ...
   <assembly-descriptor>
     ...
     <container-transaction>
       <method>
         <ejb-name>MyEJB</ejb-name>
         <method-intf>Remote</method-intf>
         <method-name>methodA</method-name>
         <method-params>
            <method-param>java.lang.String</method-param>
         </method-params>
       </method>
       <trans-attribute>Required</trans-attribute>
      </container-transaction>
      ...
   </assembly-descriptor>
   ...
</ejb-jar>

Performing Nontransactional Execution

Some EJBs might need to access resource managers that do not support an external transaction manager. The container cannot manage the transactions for such EJBs with CMT. Therefore, the EJB developer should assign the NotSupported transaction attribute to all the EJB's methods.

Rolling Back a Container-Managed Transaction

You might wonder how a container-managed transaction is rolled back. There are two ways to roll back a CMT:

  • When a System exception is thrown, the container automatically rolls back the transaction, which means that it will try to call the associated method again.

  • Application exceptions do not automatically cause a rollback. The EJB must invoke the setRollbackOnly() method of the EJBContext interface to notify the container to roll back the transaction.

The following example demonstrates both system-and application-level exception handling in rolling back a CMT:

  public class RegistrarEJB implements SessionBean{
    SessionContext ctx;
    ...
    public void registerForCourse(String courseID)
      throws InsufficientRoomException {
    try {
         rs = updateCourse(courseID);
         if (rs < 0) {
         // Application-level exception
            ctx.setRollbackOnly();
                throw new InsufficientRoomException();
        }
    } catch (SQLException ex) {
        // This is a system-level exception
        throw new EJBException
       ("Transaction rollback due to SQLException: "+ ex.getMessage());
    }
  }
...
}

The registerForCourse() method of the RegistrarEJB example illustrates the setRollbackOnly() method. If the updateCourse() method returns with insufficient room, the application exception InsufficientRoomException will be thrown. If the updates fail for any reason, these methods throw a SQLException and the registerForCourse() method throws an EJBException. Because the EJBException is a system exception, it causes the container to automatically rollback the transaction.

There are special considerations for entity beans, session beans, and message-driven beans in the event of a roll back of a CMT:

  • For a stateful session bean, the SessionSynchronization interface can be implemented to explicitly reset a bean's instance variables.

  • For an entity bean, when a rollback occurs, the EJB container will invoke ejbLoad(), which has the effect of reloading the bean's instance variables from the database.

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

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