|
|
|
@ -42,6 +42,7 @@ import java.util.concurrent.ThreadFactory;
|
|
|
|
|
import java.util.concurrent.ThreadPoolExecutor;
|
|
|
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
|
|
|
|
|
|
import static com.zaxxer.hikari.SQLExceptionOverride.Override.DO_NOT_EVICT;
|
|
|
|
|
import static com.zaxxer.hikari.pool.ProxyConnection.*;
|
|
|
|
|
import static com.zaxxer.hikari.util.ClockSource.*;
|
|
|
|
|
import static com.zaxxer.hikari.util.UtilityElf.createInstance;
|
|
|
|
@ -145,39 +146,58 @@ abstract class PoolBase
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boolean isConnectionDead(final Connection connection)
|
|
|
|
|
{
|
|
|
|
|
private boolean doIsConnectionDead(final Connection connection) throws SQLException {
|
|
|
|
|
setNetworkTimeout(connection, validationTimeout);
|
|
|
|
|
try {
|
|
|
|
|
setNetworkTimeout(connection, validationTimeout);
|
|
|
|
|
try {
|
|
|
|
|
final var validationSeconds = (int) Math.max(1000L, validationTimeout) / 1000;
|
|
|
|
|
final var validationSeconds = (int) Math.max(1000L, validationTimeout) / 1000;
|
|
|
|
|
|
|
|
|
|
if (isUseJdbc4Validation) {
|
|
|
|
|
return !connection.isValid(validationSeconds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try (var statement = connection.createStatement()) {
|
|
|
|
|
if (isNetworkTimeoutSupported != TRUE) {
|
|
|
|
|
setQueryTimeout(statement, validationSeconds);
|
|
|
|
|
}
|
|
|
|
|
if (isUseJdbc4Validation) {
|
|
|
|
|
return !connection.isValid(validationSeconds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
statement.execute(config.getConnectionTestQuery());
|
|
|
|
|
try (var statement = connection.createStatement()) {
|
|
|
|
|
if (isNetworkTimeoutSupported != TRUE) {
|
|
|
|
|
setQueryTimeout(statement, validationSeconds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
statement.execute(config.getConnectionTestQuery());
|
|
|
|
|
}
|
|
|
|
|
finally {
|
|
|
|
|
setNetworkTimeout(connection, networkTimeout);
|
|
|
|
|
}
|
|
|
|
|
finally {
|
|
|
|
|
setNetworkTimeout(connection, networkTimeout);
|
|
|
|
|
|
|
|
|
|
if (isIsolateInternalQueries && !isAutoCommit) {
|
|
|
|
|
connection.rollback();
|
|
|
|
|
}
|
|
|
|
|
if (isIsolateInternalQueries && !isAutoCommit) {
|
|
|
|
|
connection.rollback();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
private void connectionDeadException(final Connection connection, Exception e) {
|
|
|
|
|
lastConnectionFailure.set(e);
|
|
|
|
|
logger.warn("{} - Failed to validate connection {} ({}). Possibly consider using a shorter maxLifetime value.",
|
|
|
|
|
poolName, connection, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boolean isConnectionDead(final Connection connection)
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
return doIsConnectionDead(connection);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e) {
|
|
|
|
|
lastConnectionFailure.set(e);
|
|
|
|
|
logger.warn("{} - Failed to validate connection {} ({}). Possibly consider using a shorter maxLifetime value.",
|
|
|
|
|
poolName, connection, e.getMessage());
|
|
|
|
|
if (e instanceof SQLException && exceptionOverride != null &&
|
|
|
|
|
exceptionOverride.adjudicate((SQLException) e) == DO_NOT_EVICT) {
|
|
|
|
|
// try one more time, in case of failover
|
|
|
|
|
try {
|
|
|
|
|
return doIsConnectionDead(connection);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e2) {
|
|
|
|
|
connectionDeadException(connection, e2);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
connectionDeadException(connection, e);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|