Reputation: 1003
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 ?
Upvotes: 0
Views: 7090
Reputation: 3544
Links to status code explanations are literally in the same block of code you referred to: https://github.com/wwadge/bonecp/blob/master/bonecp/src/main/java/com/jolbox/bonecp/ConnectionHandle.java#L163
Upvotes: 0
Reputation: 109257
The SQL standard (ISO/IEC-9075), specifically book 2 Foundation defines SQL States. They are a 2-character class value followed by a 3-character subclass value.
Class values that begin with one of the digits '0', '1', '2', '3', or '4' or one of the simple Latin upper case letters 'A', 'B', 'C', 'D', 'E', 'F', 'G', or 'H' are returned only for conditions defined in ISO/IEC 9075 or in any other International Standard. [...] Subclass values associated with such classes that also begin with one of those 13 characters are returned only for conditions defined in ISO/IEC 9075 or some other International Standard. [...] Subclass values associated with such classes that begin with one of the digits '5', '6', '7', '8', or '9' or one of the simple Latin upper case letters 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', or 'Z' are reserved for implementation-defined conditions and are called implementation-defined subclasses.
Class values that begin with one of the digits '5', '6', '7', '8', or '9' or one of the simple Latin upper case letters 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', or 'Z' are reserved for implementation-defined exception conditions and are called implementation-defined classes. All subclass values except '000', which means no subclass, associated with such classes are reserved for implementation-defined conditions and are called implementation-defined subclasses.
(from SQL:2011 book 2)
These standard classes (and standard defined subclasses) are listed in book 2 (foundation), 3 (CLI), 4 (PSM), 9 (MED), 10 (OLB), 13 (JRT) and 14 (XML). It also lists whether something is an exception, warning, successful completion condition or no-data completion condition (not all SQL states are errors!)
For example the sqlstates listed in your question are:
08001
: class: connection exception, subclass: SQL-client unable to establish SQL-connection08007
: class: connection exception, subclass: transaction resolution unknown08S01
: class: connection exception, subclass: begins with S, so is an implementation-defined subclass (it is defined in ODBC as Communication link failure)57P01
: class: begins with 5, so is an implementation defined-class, it seems to be the PostgreSQL sqlstate for ADMIN SHUTDOWNHY000
: class: CLI-specific condition (defined in book 3, CLI), subclass: (no subclass)HY000
is a very generic error as some databases or drivers will return it for any error that has no specific sqlstate, so it is usually treated as fatal. I do that BoneCP's behavior to treat it as a reason to kill off the entire connection pool a bit overkill as HY000
could also be thrown for relatively benign errors. The other sqlstates are usually an indication of a problem connecting to the database (08001
, 08S01
) or unavailability of the database (57P01
), or a problem with the database itself (08007
).
Upvotes: 2
Reputation: 1109635
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.
Upvotes: 5