Application Techniques



Using EJB Session Beans to Control an Entity Bean's Transaction Scope

How to write an EJB application that uses session beans to control the transaction scope of one or more entity beans.

About this technique

Details

Category

Enterprise JavaBean Techniques

Description

You'll learn about:

Related reading

See the part on developing Enterprise JavaBeans in the Programmer's Guide

Writing a session bean with bean-demarcated transactions   Top of page

To write a session bean with bean-demarcated transactions you:

Using the Java Transaction API   Top of page

At startup, the SilverStream Server creates a transaction object. This transaction object can be accessed via the container's context. (This context is passed to the session bean when it is instantiated.) If you save the context (in the setSessionContext() method) you can call the getUserTransaction() method to obtain the transaction object.

To begin a transaction, call:

  UserTransaction utx = null; 
  utx = m_context.getUserTransaction();   
  utx.begin(); 

For this example, the m_context is a SessionContext, and it was populated in the setSessionContext() method.

To commit a transaction, call:

  utx.commit(); 

To rollback a transaction, call:

  utx.rollback(); 

A closer look at the BankDemo's transactional methods   Top of page

The following methods manage access to entity bean and wrap the bean within a transaction to limit database reads which might enhance performance:

The transferBetweenAccounts() method requires a transaction because the operation must be atomic.

Getting the session context

The m_context is declared in the declarations section as follows:

  protected SessionContext m_context; 

The setSessionContext() method looks like this:

  public void setSessionContext(javax.ejb.SessionContext 
     psessionContext) throws java.rmi.RemoteException 
  { 
     m_context = psessionContext; 
  } 

Doing a deposit

Here's how the depositToAccount() method begins, commits or rollsback a transaction.

  // Find the account record for the account number passed in to 
  //this method. 
  EBAccount ebAccount = null; 
  UserTransaction utx = null; 
  try { 
       utx = m_context.getUserTransaction();   
        utx.begin(); 
   
      EBAccountPrimaryKey pkAccount = new EBAccountPrimaryKey(); 
      pkAccount.m_account_number = psAccountNumber; 
      ebAccount = (EBAccount)     m_EBAccountHome.findByPrimaryKey(pkAccount); 
  // If we didn't find it, throw an exception. 
      if (ebAccount == null){ 
       utx.rollback; 
       String sErrorMessage = 
         BankDemoConstants.MSG_NO_ACCOUNT_FOUND; 
       throw new BankDemoException(sErrorMessage); 
      } 
  // This is where we call the EBAccount to make the deposit. 
  ebAccount.accountDeposit(pbdTransactionAmount); 
      utx.commit(); 
      utx = null; 
      } 
     catch(Exception e) 
    { 
  // If we still have a value in utx, we need to roll it back. 
       
        if (utx != null) { 
          try { 
               utx.rollback();  
               utx = null;  
                 } 
          catch (Exception excp) {} 
         } 
  // If it failed, just rethrow the exception thrown by the 
  //EBAccount. 
           throw new BankDemoException(e.toString()); 
  } 

Making sure the entity beans use the correct transaction context   Top of page

The container always manages an entity bean's participation in a transaction. You specify how the container handles a method by adding an entry in the deployment descriptor. At runtime, the container ensures that the methods are called within the correct transaction context based on the deployment descriptor entries.

BankDemo transaction attributes

For the BankDemo, we want the session bean to create the transaction context, and we want the entity beans to run within that context. We don't want the container to change the transaction context that the session bean has created. For this reason, we want all of the entity bean's methods to run using the Supported attribute. Using the Supported attribute will allow the container to call each method within the transaction of the caller's transaction context, that is, the SBBankATM's transaction context.

In SilverStream, you set these attributes by creating a Transaction Entry in the Application Assembly portion of the deployment descriptor shown here.

In SilverStream, all methods default to the Supports attribute, so you do not have to specify a Transaction Entry to use it. However, you might want to set it for documentation purposes.

    For more information on the transaction attributes, see section 11.6.2 of the EJB Specification.

Specifying session bean transaction management type   Top of page

The Property Inspector for the SBBankATMBean session bean shows this:

Understanding transaction scope and propagation

For container-demarcated transactions, the container makes sure that a specific method is always executed within the appropriate transaction context based on the deployment descriptor. In the BankDemo, all methods use the Supports transaction attribute. The following diagram shows how the Session Bean SBBankATMBean controls the transaction context and the container honors that control.

Reasons why you might want to use transactions

In SilverStream, there are two reasons that you might want to control transactions from a session bean:






Copyright © 2000, SilverStream Software, Inc. All rights reserved.