+

Search Tips   |   Advanced Search

Example: Handling connection exceptions for session beans in bean-managed database transactions


The following code sample demonstrates the options for addressing stale connection exceptions. We can set different transaction management and connection management parameters, such as the number of operation retries, and the connection timeout interval.

//===================START_PROLOG======================================

//

//   5630-A23, 5630-A22, 
//   (C) COPYRIGHT International Business Machines Corp. 2002,2008

//   All Rights Reserved

//   Licensed Materials - Property of IBM

//   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.

//

//   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING

//   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR

//   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR

//   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF

//   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR

//   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE

//   OR PERFORMANCE OF THIS SOFTWARE.

//

//===================END_PROLOG========================================
 package WebSphereSamples.ConnPool;
 import java.util.*;
 import java.sql.*;
 import javax.sql.*;
 import javax.ejb.*;
 import javax.naming.*;
 import javax.transaction.*;
 import com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException;
 import com.ibm.websphere.rsadapter.WSCallHelper;

/**********************************************************************************
* This bean is designed to demonstrate Database Connections in a                  *
* Bean-Managed Transaction Session Bean.  Its transaction attribute               *
* should be set to TX_BEANMANAGED.                                                 
**********************************************************************************/ 
public class ShowEmployeesBMTBean implements SessionBean {
     private javax.ejb.SessionContext mySessionCtx = null;
     final static long serialVersionUID = 3206093459760846163L;

     private javax.sql.DataSource ds;

     private javax.transaction.UserTransaction userTran;


//************************************************************************************

//* ejbActivate calls the getDS method, which makes the JNDI lookup for the DataSource

//* Because the DataSource lookup is in a separate method, we can also invoke it from     

//* the getEmployees method in the case where the DataSource field is null.          

//************************************************************************************ 
public void ejbActivate() throws java.rmi.EJBException {
     getDS();
}
/**
 * ejbCreate method 
 * @exception javax.ejb.CreateException
 * @exception java.rmi.EJBException
 */ public void ejbCreate() throws javax.ejb.CreateException, java.rmi.EJBException {}
/**
 * ejbPassivate method 
 * @exception java.rmi.EJBException
 */ public void ejbPassivate() throws java.rmi.EJBException {}
/**
 * ejbRemove method 
 * @exception java.rmi.EJBException
 */ public void ejbRemove() throws java.rmi.EJBException {}


//************************************************************************************

//* The getEmployees method runs the database query to retrieve the employees.           

//* The getDS method is only called if the DataSource or userTran variables are null.

//* If a stale connection occurs, the bean retries the transaction 5 times,     

//* then throws an EJBException.

//************************************************************************************
 public Vector getEmployees() throws EJBException {
   Connection conn  = null;
   Statement stmt = null;
   ResultSet rs = null;
   Vector employeeList = new Vector();

   
// Set retryCount to the number of times you would like to retry after a
   
// stale connection
   int retryCount = 5;  
    
   
// If the Database code processes successfully, we will set error = false
   boolean error = true;
   
   if (ds == null || userTran == null) getDS();
   do
   {          
         try
         { 
            
//try/catch block for UserTransaction work
            
//Begin the transaction
            userTran.begin();
            try
            { 
               
//try/catch block for database work
               
//Get a Connection object conn using the DataSource factory.
               conn = ds.getConnection();
               
// Run DB query using standard JDBC coding.
               stmt = conn.createStatement();
               String query   = "Select FirstNme, MidInit, LastName " + 
                   "from Employee ORDER BY LastName";
               rs   = stmt.executeQuery(query);
               while (rs.next())
               {
                  employeeList.addElement(rs.getString(3) + ", " + rs.getString(1) + " " + rs.getString(2));
               }
               
//Set error to false, as all database operations are successfully completed
               error = false;
            } 
            catch (SQLException sqlX)
            {
              if (WSCallHelper.getDataStoreHelper(ds).isConnectionError(sqlX))
              {
                
// This exception indicates that the connection to the database is no longer valid.
                
// Rollback the transaction, and throw an exception to the client indicating they
                
// can retry the transaction if desired.

                System.out.println("Stale connection: " +
                se.getMessage());
                userTran.rollback();
                if (--retryCount == 0)
                {
                  
//If we have already retried the requested number of times, throw an EJBException.
                  throw new EJBException("Transaction Failure: " + sqlX.toString());
                } 
                else
                {
                  System.out.println("Retrying transaction, retryCount = " +          
                         retryCount);
                }
              } 
              else if (sqlX instanceof ConnectionWaitTimeoutException
                    || sqlX instanceof SQLTransientConnectionException
                       && sqlX.getCause() instanceof ConnectionWaitTimeoutException)
              {
                
// This exception is thrown if a connection can not be obtained from the                 
                
// pool within a configurable amount of time.  Frequent occurrences of
                
// this exception indicate an incorrectly tuned connection pool

                System.out.println("Connection request timed out: " + 
                sqlX.getMessage());
                userTran.rollback();
                throw new EJBException("Transaction failure: " + sqlX.getMessage());
              } 
              else
              {                   
          
// This catch handles all other SQL Exceptions
                System.out.println("SQL Exception during get connection or process SQL: " +
                    sqlX.getMessage());
                userTran.rollback();
                throw new EJBException("Transaction failure: " + sqlX.getMessage());
              } 
            finally
            {
              
// Always close the connection in a finally statement to ensure proper 
              
// closure in all cases. Closing the connection does not close and 
              
// actual connection, but releases it back to the pool for reuse.

              if (rs != null) {
               try {
                  rs.close();
               } 
               catch (Exception e) {
                  System.out.println("Close Resultset Exception: " + e.getMessage());
               }
            }
            if (stmt != null) {
               try {
                  stmt.close();
 } 
            catch (Exception e) {
               System.out.println("Close Statement Exception: " + e.getMessage());
            }
         }         
         if (conn != null) {
            try {
               conn.close();
            } 
            catch (Exception e) {
               System.out.println("Close connection exception: " + e.getMessage());
            }
         }
      }            
      if (!error) {
         
//Database work completed successfully, commit the transaction
         userTran.commit();
      }
      
//Catch UserTransaction exceptions
      } 
      catch (NotSupportedException nse) {


//Thrown by UserTransaction begin method if the thread is already associated with a 

//transaction and the Transaction Manager implementation does not support nested transactions.

System.out.println("NotSupportedException on User Transaction begin: " + nse.getMessage()); throw new EJBException("Transaction failure: " + nse.getMessage()); } catch (RollbackException re) { //Thrown to indicate that the transaction has been rolled back rather than committed. System.out.println("User Transaction Rolled back! " + re.getMessage()); throw new EJBException("Transaction failure: " + re.getMessage()); } catch (SystemException se) { //Thrown if the transaction manager encounters an unexpected error condition System.out.println("SystemException in User Transaction: "+ se.getMessage()); throw new EJBException("Transaction failure: " + se.getMessage()); } catch (Exception e) { //Handle any generic or unexpected Exceptions System.out.println("Exception in User Transaction: " + e.getMessage()); throw new EJBException("Transaction failure: " + e.getMessage()); } } while (error); return employeeList; } /** * getSessionContext method comment * @return javax.ejb.SessionContext */ public javax.ejb.SessionContext getSessionContext() { return mySessionCtx; } //************************************************************************************ //* The getDS method performs the JNDI lookup for the DataSource. //* This method is called from ejbActivate, and from getEmployees if the DataSource //* object is null. //************************************************************************************ private void getDS() { try { Hashtable parms = new Hashtable(); parms.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory"); InitialContext ctx = new InitialContext(parms); // Perform a naming service lookup to get the DataSource object. ds = (DataSource)ctx.lookup("java:comp/env/jdbc/SampleDB"); //Create the UserTransaction object userTran = mySessionCtx.getUserTransaction(); } catch (Exception e) { System.out.println("Naming service exception: " + e.getMessage()); e.printStackTrace(); } } /** * setSessionContext method * @param ctx javax.ejb.SessionContext * @exception java.rmi.EJBException */ public void setSessionContext(javax.ejb.SessionContext ctx) throws java.rmi.EJBException { mySessionCtx = ctx; } }

//===================START_PROLOG======================================

//

//   5630-A23, 5630-A22, 
//   (C) COPYRIGHT International Business Machines Corp. 2002,2008

//   All Rights Reserved

//   Licensed Materials - Property of IBM

//   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.

//

//   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING

//   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR

//   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR

//   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF

//   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR

//   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE

//   OR PERFORMANCE OF THIS SOFTWARE.

//

//===================END_PROLOG========================================
 package WebSphereSamples.ConnPool;

/**
 * This is a Home interface for the Session Bean
 */ public interface ShowEmployeesBMTHome extends javax.ejb.EJBHome {

/**
 * create method for a session bean
 * @return WebSphereSamples.ConnPool.ShowEmployeesBMT
 * @exception javax.ejb.CreateException
 * @exception java.rmi.RemoteException
 */ WebSphereSamples.ConnPool.ShowEmployeesBMT create() throws javax.ejb.CreateException,     java.rmi.RemoteException;
}

//===================START_PROLOG======================================

//

//   5630-A23, 5630-A22, 
//   (C) COPYRIGHT International Business Machines Corp. 2002,2008

//   All Rights Reserved

//   Licensed Materials - Property of IBM

//   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.

//

//   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING

//   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR

//   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR

//   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF

//   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR

//   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE

//   OR PERFORMANCE OF THIS SOFTWARE.

//

//===================END_PROLOG========================================
 package WebSphereSamples.ConnPool;

/**
 * This is an Enterprise Java Bean Remote Interface
 */ public interface ShowEmployeesBMT extends javax.ejb.EJBObject {

/**
 * 
 * @return java.util.Vector
 */ java.util.Vector getEmployees() throws java.rmi.RemoteException, javax.ejb.EJBException;
}




 

Related


Administrative console buttons
Administrative console page features