Search code examples
javajdbcsqlexception

How to detect the SQL error state of SQLException


I am trying to make a JDBC connection pool component, but I have met a problem. That is: How to detect the error state of java.sql.SQLException. It's said that the state should follow SQL2003 conventions and XOPEN SQL conventions in JDK documentations. But I can't find any documents about these two conventions.Could someone provide it for me?

I want to know what every state stands for, so I can decide when to close the connection fully or reconnect.

I have refered to source code of BoneCP. Here is a part which will be actived when a SQLException occurs :

    ImmutableSet<String> sqlStateDBFailureCodes = ImmutableSet.of("08001", "08007", "08S01", "57P01", "HY000"); 
    String state = e.getSQLState();
        ConnectionState connectionState = this.getConnectionHook() != null ? this.getConnectionHook().onMarkPossiblyBroken(this, state, e) : ConnectionState.NOP; 
        if (state == null){ // safety;
            state = "08999"; 
        }

        if (((sqlStateDBFailureCodes.contains(state) || connectionState.equals(ConnectionState.TERMINATE_ALL_CONNECTIONS)) && this.pool != null) && this.pool.getDbIsDown().compareAndSet(false, true) ){
            logger.error("Database access problem. Killing off all remaining connections in the connection pool. SQL State = " + state);
            this.pool.connectionStrategy.terminateAllConnections();
            this.pool.poisonAndRepopulatePartitions();
        }
char firstChar = state.charAt(0);
        if (connectionState.equals(ConnectionState.CONNECTION_POSSIBLY_BROKEN) || state.equals("40001") || 
                state.startsWith("08") ||  (firstChar >= '5' && firstChar <='9') /*|| (firstChar >='I' && firstChar <= 'Z')*/){
            this.possiblyBroken = true;
        }

        // Notify anyone who's interested
        if (this.possiblyBroken  && (this.getConnectionHook() != null)){
            this.possiblyBroken = this.getConnectionHook().onConnectionException(this, state, e);
        }

According to these code, boneCP considers it as a database server crash when the state of SQLException equals one of "08001", "08007", "08S01", "57P01", "HY000".

But why, what do these states stand for ?


Solution

  • The first 2 characters are specified in "Table_23-SQLSTATE_class_and_subclass_values" of the SQL92 specification.

    Here's an extract of relevance:

    00  success completion
    01  warning
    02  no data
    07  dynamic SQL error
    08  connection exception
    0A  feature not supported
    21  cardinality violation
    22  data exception
    23  integrity constraint violation
    24  invalid cursor state
    25  invalid transaction state
    26  invalid SQL statement name
    27  triggered data change violation
    28  invalid authorization specification
    2A  direct SQL syntax error or access rule violation
    2B  dependent privilege descriptors still exist
    2C  invalid character set name
    2D  invalid transaction termination
    2E  invalid connection name
    33  invalid SQL descriptor name
    34  invalid cursor name
    35  invalid condition number
    37  dynamic SQL syntax error or access rule violation
    3C  ambiguous cursor name
    3D  invalid catalog name
    3F  invalid schema name
    40  transaction rollback
    42  syntax error or access rule violation
    44  with check option violation
    HZ  remote database access
    

    The remaining characters are DB vendor dependent. So it's generally recommended to just perform a startsWith() check.