*/
protected SQLException markPossiblyBroken(SQLException e) {
String state = e.getSQLState();
boolean alreadyDestroyed = false;
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 this connection and all remaining connections in the connection pool. SQL State = " + state);
this.pool.connectionStrategy.terminateAllConnections();
this.pool.destroyConnection(this);
this.logicallyClosed.set(true);
alreadyDestroyed = true;
for (int i=0; i < this.pool.partitionCount; i++) {
// send a signal to try re-populating again.
this.pool.partitions[i].getPoolWatchThreadSignalQueue().offer(new Object()); // item being pushed is not important.
}
}
//case where either the connection is closed or
//two concurrent connections loose connections with
//the 08S01 code but one one is killed in the code
//above give dbIsDown is set for the first connection
if (state.equals("08003") || sqlStateDBFailureCodes.contains(state) || e.getCause() instanceof SocketException) {
if (!alreadyDestroyed) {
this.pool.destroyConnection(this);
this.logicallyClosed.set(true);
getOriginatingPartition().getPoolWatchThreadSignalQueue().offer(new Object()); // item being pushed is not important.
}
}
// SQL-92 says:
// Class values that begin with one of the <digit>s '5', '6', '7',
// '8', or '9' or one of the <simple Latin upper case letter>s 'I',
// 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
// 'W', 'X', 'Y', or 'Z' are reserved for implementation-specified
// conditions.
// FIXME: We should look into this.connection.getMetaData().getSQLStateType();
// to determine if we have SQL:92 or X/OPEN sqlstatus codes.
// char firstChar = state.charAt(0);
// if it's a communication exception, a mysql deadlock or an implementation-specific error code, flag this connection as being potentially broken.
// state == 40001 is mysql specific triggered when a deadlock is detected
// state == HY000 is firebird specific triggered when a connection is broken
char firstChar = state.charAt(0);
if (connectionState.equals(ConnectionState.CONNECTION_POSSIBLY_BROKEN) || state.equals("40001") ||
state.equals("HY000") ||
state.startsWith("08") || (firstChar >= '5' && firstChar <='9') /*|| (firstChar >='I' && firstChar <= 'Z')*/){
this.possiblyBroken = true;
}