Exceptions pertaining to data access
All CMP beans under the EJB 2.0 Specification receive a standard EJBException when an operation fails.
JDBC applications receive a standard SQLException if any JDBC operation fails.
WAS provides special exceptions for its relational resource adapter, to indicate that the connection currently held is no longer valid. The ConnectionWaitTimeoutException indicates that the application timed out trying to get a connection. The StaleConnectionException indicates that the connection is no longer valid.
Connection wait timeout
The ConnectionWaitTimeout exception indicates that the application has waited for the number of seconds specified by the connection timeout setting and has not received a connection. This situation can occur when the pool is at maximum size and all of the connections are in use by other applications for the duration of the wait. In addition, there are no connections currently in use that the application can share because either the connection properties do not match, or the connection is in a different transaction.
For connection factories, the ConnectionWaitTimeout throws a ResourceException whose class is...com.ibm.websphere.ce.j2c.ConnectionWaitTimeoutException
The data source throws an SQLException subclass called...com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException
WAS provides a special subclass of java.sql.SQLException when using connection pooling to access a relational database. This...com.ibm.websphere.ce.cm.StaleConnectionException...subclass uses the relational resource adapter, and is used to indicate that the connection currently held is no longer valid. This situation can occur for many reasons, including...
- The application tries to get a connection and fails, as when the database is not started.
- A connection is no longer usable because of a database failure. When an application tries to use a previously obtained connection, the connection is no longer valid. In this case, all connections currently in use by the application can get this error when they try to use the connection.
- The application tries to use a JDBC resource, such as a statement, obtained on a stale connection.
One ramification of having the transaction manager close the connections and return the connection to the free pool after a transaction ends, is that an application cannot obtain a connection in one transaction and try to use it in another transaction. If the application tries this, a StaleConnectionException is thrown because the connection is already closed.
In the case of trying to use an orphaned connection or a connection cleaned up by auto connection cleanup, a StaleConnectionException indicates that the application has attempted to use a connection already returned to the connection pool. It does not indicate an actual problem with the connection. However, other cases of a StaleConnectionException indicate that the connection to the database has gone bad, or stale. Once a connection has gone stale, you cannot recover it, and completely close the connection rather than returning it to the pool.
Detecting stale connections
When a connection to the database becomes stale, operations on that connection result in an SQLException from the JDBC driver. Because an SQLException is a rather generic exception, it contains state and error code values that you can use to determine the meaning of the exception. However, the meanings of these states and error codes vary depending on the database vendor. The connection pooling run time maintains a mapping of which SQL state and error codes indicate a StaleConnectionException for each database vendor supported. When the connection pooling run time catches any SQLException, it checks to see if this SQLException is considered a StaleConnectionException for the database server in use.
Recovering from stale connections
Recovering from stale connections is a joint effort between the appserver run time and the application developer. From an application server perspective, the connection pool is purged based on its PurgePolicy setting.
Explicitly catching a StaleConnectionException is not required in an application. Because applications are already required to catch java.sql.SQLException, and StaleConnectionException extends SQLException, StaleConnectionException can be thrown from any method that is declared to throw SQLException, and is caught automatically in the general catch-block. However, explicitly catching StaleConnectionException makes it possible for an application to recover from bad connections. When application code catches StaleConnectionException, it should take explicit steps to handle the exception.