Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/main/java/com/zaxxer/hikari/pool/HikariPool.java
Original file line number Diff line number Diff line change
Expand Up @@ -705,14 +705,18 @@ private SQLException createTimeoutException(long startTime)
String sqlState = null;
int errorCode = 0;
final var originalException = getLastConnectionFailure();
Long lastConnectionFailureTimestamp = getLastConnectionFailureTimestamp();
if (originalException instanceof SQLException) {
sqlState = ((SQLException) originalException).getSQLState();
errorCode = ((SQLException) originalException).getErrorCode();
}
final var connectionException = new SQLTransientConnectionException(
poolName + " - Connection is not available, request timed out after " + elapsedMillis(startTime) + "ms " +
"(total=" + getTotalConnections() + ", active=" + getActiveConnections() + ", idle=" + getIdleConnections() + ", waiting=" + getThreadsAwaitingConnection() + ")",
sqlState, errorCode, originalException);
String errorDescription = poolName + " - Connection is not available, request timed out after " + elapsedMillis(startTime) + "ms " +
"(total=" + getTotalConnections() + ", active=" + getActiveConnections() + ", idle=" + getIdleConnections() + ", waiting=" + getThreadsAwaitingConnection() + ")";
if (lastConnectionFailureTimestamp != null && lastConnectionFailureTimestamp != 0) {
errorDescription += " - The last connection failure (appended as the next exception below) happened " +
elapsedDisplayString(lastConnectionFailureTimestamp, currentTime()) + " ago.";
}
final var connectionException = new SQLTransientConnectionException(errorDescription, sqlState, errorCode, originalException);
if (originalException instanceof SQLException) {
connectionException.setNextException((SQLException) originalException);
}
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/com/zaxxer/hikari/pool/PoolBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ abstract class PoolBase

volatile String catalog;
final AtomicReference<Throwable> lastConnectionFailure;
final AtomicLong lastConnectionFailureTimestamp;
final AtomicLong connectionFailureTimestamp;

long connectionTimeout;
Expand Down Expand Up @@ -116,6 +117,7 @@ abstract class PoolBase
this.connectionTimeout = config.getConnectionTimeout();
this.validationTimeout = config.getValidationTimeout();
this.lastConnectionFailure = new AtomicReference<>();
this.lastConnectionFailureTimestamp = new AtomicLong();
this.connectionFailureTimestamp = new AtomicLong();

initializeDataSource();
Expand Down Expand Up @@ -185,6 +187,7 @@ boolean isConnectionDead(final Connection connection)
}
catch (Exception e) {
lastConnectionFailure.set(e);
lastConnectionFailureTimestamp.set(currentTime());
logger.warn("{} - Failed to validate connection {} ({}). Possibly consider using a shorter maxLifetime value.",
poolName, connection, e.getMessage());
return true;
Expand All @@ -196,6 +199,10 @@ Throwable getLastConnectionFailure()
return lastConnectionFailure.get();
}

Long getLastConnectionFailureTimestamp(){
return lastConnectionFailureTimestamp.get();
}

public DataSource getUnwrappedDataSource()
{
return dataSource;
Expand Down Expand Up @@ -378,6 +385,7 @@ private Connection newConnection(final boolean isEmptyPool) throws Exception
setupConnection(connection);

lastConnectionFailure.set(null);
lastConnectionFailureTimestamp.set(0);
connectionFailureTimestamp.set(0);

logger.debug("{} - Established new connection ({})", poolName, id);
Expand All @@ -397,6 +405,7 @@ private Connection newConnection(final boolean isEmptyPool) throws Exception
}

lastConnectionFailure.set(t);
lastConnectionFailureTimestamp.set(currentTime());
throw t;
}
finally {
Expand Down