Example: Developing session bean with bean managed transaction
//===================START_PROLOG====================================== // // 5630-A23, 5630-A22, // (C) COPYRIGHT International Business Machines Corp. 2002 // All Rights Reserved // Licensed Materials - Property of IBM // US Government Users Restricted Rights - Use, duplication or // 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.rmi.RemoteException; import java.util.*; import java.sql.*; import javax.sql.*; import javax.ejb.*; import javax.naming.*; import javax.transaction.*; /************************************************************************************* * 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.RemoteException { getDS(); } /** * ejbCreate method * @exception javax.ejb.CreateException * @exception java.rmi.RemoteException */ public void ejbCreate() throws javax.ejb.CreateException, java.rmi.RemoteException {} /** * ejbPassivate method * @exception java.rmi.RemoteException */ public void ejbPassivate() throws java.rmi.RemoteException {} /** * ejbRemove method * @exception java.rmi.RemoteException */ public void ejbRemove() throws java.rmi.RemoteException {} //************************************************************************************ //* 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 StaleConnectionException 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 //StaleConnectionException" 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 (com.ibm.websphere.ce.cm.StaleConnectionException se) { // 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 Exception during get connection or process SQL: " + 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: " + se.toString()); } else { System.out.println("Retrying transaction, retryCount = " + retryCount); } } catch (com.ibm.ejs.cm.pool.ConnectionWaitTimeoutException cw) { // 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: " + cw.getMessage()); userTran.rollback(); throw new EJBException("Transaction failure: " + cw.getMessage()); } catch (SQLException sq) { // This catch handles all other SQL Exceptions System.out.println("SQL Exception during get connection or process SQL: " + sq.getMessage()); userTran.rollback(); throw new EJBException("Transaction failure: " + sq.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 { // Note the new Initial Context Factory interface available in WebSphere 4.0 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.RemoteException */ public void setSessionContext(javax.ejb.SessionContext ctx) throws java.rmi.RemoteException { mySessionCtx = ctx; } }
//===================START_PROLOG====================================== // // 5630-A23, 5630-A22, // (C) COPYRIGHT International Business Machines Corp. 2002 // All Rights Reserved // Licensed Materials - Property of IBM // US Government Users Restricted Rights - Use, duplication or // 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 // All Rights Reserved // Licensed Materials - Property of IBM // US Government Users Restricted Rights - Use, duplication or // 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; }