以下代码样本说明了在出现旧连接异常的情况下如何回滚事务以及如何向 Bean 客户机发出异常。
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;
}
}
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;
}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;
}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);
}
}
本文展示了一个EJB Session Bean的实例,该Bean用于演示如何在出现旧连接异常时回滚事务并抛出异常给客户端,同时介绍了如何通过JNDI查找数据源。
2752

被折叠的 条评论
为什么被折叠?



