+

Search Tips   |   Advanced Search

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


The following code sample demonstrates how to roll back transactions and issue exceptions to the bean client in cases of stale connection exceptions.

//===================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 com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException;
 import com.ibm.websphere.rsadapter.WSCallHelper;

/*************************************************************************************
* This bean is designed to demonstrate Database Connections in a                      
* Container Managed Transaction Session Bean.  Its transaction attribute               *
* should be set to TX_REQUIRED or TX_REQUIRES_NEW.                                     *
**************************************************************************************
*/ public class ShowEmployeesCMTBean implements SessionBean {
     private javax.ejb.SessionContext mySessionCtx = null;
     final static long serialVersionUID = 3206093459760846163L;
     
     private javax.sql.DataSource ds;


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

//* ejbActivate calls the getDS method, which does 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 variable is null.  

//* Because this session bean uses Container Managed Transactions, it cannot retry the 
//* transaction on a StaleConnectionException.  However, it can throw an exception to

//* its client indicating that the operation is retriable.

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

   if (ds == null) getDS();
        
   try
   {
      
// 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));
      }                           
   } 
   catch (SQLException sqlX)
   {
     
// Determine if the connection is stale
     if (WSCallHelper.getDataStoreHelper(ds).isConnectionError(sqlX))
     {
       
// This exception indicates that the connection to the database is no longer valid.
       
// Roll back the transaction, and throw an exception to the client indicating they
       
// can retry the transaction if desired.

       System.out.println("Connection is stale: " + sqlX.getMessage());
       System.out.println("Rolling back transaction and throwing  RetryableConnectionException");

       mySessionCtx.setRollbackOnly();
       throw new RetryableConnectionException(sqlX.toString());
     }
     
// Determine if the connection request timed out.
     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 Wait Timeout Exception during get connection or process SQL: " +
       sqlX.getMessage());
       throw sqlX instanceof ConnectionWaitTimeoutException ?
             sqlX :
             (ConnectionWaitTimeoutException) sqlX.getCause();
     } 
     else
     {
       
//Throwing a remote exception will automatically roll back the container managed 
       
//transaction

       System.out.println("SQL Exception during get connection or process SQL: " +
                    sqlX.getMessage());
       throw sqlX;
     } 


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()); } }

return employeeList; } /** * getSessionContext method * @return javax.ejb.SessionContext */ public javax.ejb.SessionContext getSessionContext() { return mySessionCtx; } //************************************************************************************ //* The getDS method performs the JNDI lookup for the data source. //* This method is called from ejbActivate, and from getEmployees if the data source //* 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"); } 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 ShowEmployeesCMTHome extends javax.ejb.EJBHome {

/**
 * create method for a session bean
* @return WebSphereSamples.ConnPool.ShowEmployeesCMT
 * @exception javax.ejb.CreateException
 * @exception java.rmi.RemoteException
 */ WebSphereSamples.ConnPool.ShowEmployeesCMT 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 ShowEmployeesCMT extends javax.ejb.EJBObject {

/**
 * 
 * @return java.util.Vector
 */ java.util.Vector getEmployees() throws java.sql.SQLException, java.rmi.RemoteException,  ConnectionWaitTimeoutException, WebSphereSamples.ConnPool.RetryableConnectionException;
}

//===================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;

/**
 * Exception indicating that the operation can be retried
 * Creation date: (4/2/2001 10:48:08 AM)
 * @author: Administrator
 */ public class RetryableConnectionException extends Exception {
/**
 * RetryableConnectionException constructor.
 */ public RetryableConnectionException() {
     super();
}
/**
 * RetryableConnectionException constructor.
 * @param s java.lang.String
 */ public RetryableConnectionException(String s) {
     super(s);
}
}




 

Related


Administrative console buttons
Administrative console page features