Validating a DB Connection

You may have been tempted to execute Connection.isClosed() to test whether a connection is live and can be reused. This is however not sufficient as the Sun JDBC API guide states:

“Note that the method Connection.isClosed is guaranteed to return true only when it is called after the method Connection.close has been called. As a result, a programmer cannot depend on this method to indicate whether a connection is valid or not. Instead, a typical JDBC client can determine that a connection is invalid by catching the exception that is thrown when a JDBC operation is attempted.”

The only safe way of ensuring that a connection is valid is to execute a tiny query and catch any SQLExceptions thrown. If no exceptions are thrown, you can go on and using that connection.

If any exceptions are thrown, it is safest to close that connection, set the reference to null and create a new connection.

What query to execute?

It would be nice to execute a general (database independent) method like Connection.getMetaData(). Unfortunately I have seen some indication that this may be successful even when a connection is invalid.

To be on the safe side it is best to execute a query like “SELECT COUNT(*) FROM WHERE 1 = -1″. We are using SQL server so the table sysusers is a safe bet:

    /**
     * A method that tests whether a connection is valid by executing
simple query and catch any exceptions

     */
    private boolean connectionIsValid(Connection dbConn) {
        //log.debug("ENTER connectionIsValid(): "+dbConn);        
        boolean result = true;
        
        PreparedStatement psr = null;
        try {
            //Prepared statement is used to cache the compiled SQL
            psr = dbConn.prepareStatement("SELECT COUNT(*) FROM sysusers WHERE 1 = -1");
            psr.executeQuery();
        catch (SQLException e) {
            log.debug("Excpetion occured, connection is not valid. "+e.getMessage());
            try {
                dbConn.close()//dbConn is never null at this point
                dbConn=null;
            catch (Exception ee) {
                //quite
            }
            result = false;
        finally {
            try {
                //free up resource kept by the test statement
                if (psr!=null) {
                    psr.close();
                }               
                psr=null;
            catch (Exception e) {
                //quite
            }
        }        
        //log.debug("EXIT connectionIsValid(): "+result);
        return result;
    }