diff --git a/pom.xml b/pom.xml
index 439442b3b..7e7ba49b5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,11 +43,11 @@
3.7.7
4.13.5
2.5.4
- 42.5.1
+ 42.7.4
2.18.0
1.7.36
1.5
-
2.1.212
+ 2.3.232
4.13.2
1.20.1
diff --git a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java
index 58616880f..002fcd692 100644
--- a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java
+++ b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java
@@ -481,7 +481,7 @@ int[] getPoolStateCounts()
private PoolEntry createPoolEntry()
{
try {
- final var poolEntry = newPoolEntry();
+ final var poolEntry = newPoolEntry(getTotalConnections() == 0);
final var maxLifetime = config.getMaxLifetime();
if (maxLifetime > 0) {
@@ -503,8 +503,7 @@ private PoolEntry createPoolEntry()
}
catch (ConnectionSetupException e) {
if (poolState == POOL_NORMAL) { // we check POOL_NORMAL to avoid a flood of messages if shutdown() is running concurrently
- logger.error("{} - Error thrown while acquiring connection from data source", poolName, e.getCause());
- lastConnectionFailure.set(e);
+ logger.debug("{} - Error thrown while acquiring connection from data source", poolName, e.getCause());
}
}
catch (Exception e) {
diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolBase.java b/src/main/java/com/zaxxer/hikari/pool/PoolBase.java
index 5be87b0eb..9e7f766e1 100644
--- a/src/main/java/com/zaxxer/hikari/pool/PoolBase.java
+++ b/src/main/java/com/zaxxer/hikari/pool/PoolBase.java
@@ -41,13 +41,13 @@
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import static com.zaxxer.hikari.pool.ProxyConnection.*;
import static com.zaxxer.hikari.util.ClockSource.*;
import static com.zaxxer.hikari.util.UtilityElf.createInstance;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.*;
abstract class PoolBase
{
@@ -60,6 +60,7 @@ abstract class PoolBase
volatile String catalog;
final AtomicReference lastConnectionFailure;
+ final AtomicLong connectionFailureTimestamp;
long connectionTimeout;
long validationTimeout;
@@ -110,6 +111,7 @@ abstract class PoolBase
this.connectionTimeout = config.getConnectionTimeout();
this.validationTimeout = config.getValidationTimeout();
this.lastConnectionFailure = new AtomicReference<>();
+ this.connectionFailureTimestamp = new AtomicLong();
initializeDataSource();
}
@@ -198,9 +200,9 @@ public DataSource getUnwrappedDataSource()
// PoolEntry methods
// ***********************************************************************
- PoolEntry newPoolEntry() throws Exception
+ PoolEntry newPoolEntry(final boolean isEmptyPool) throws Exception
{
- return new PoolEntry(newConnection(), this, isReadOnly, isAutoCommit);
+ return new PoolEntry(newConnection(isEmptyPool), this, isReadOnly, isAutoCommit);
}
void resetConnectionState(final Connection connection, final ProxyConnection proxyConnection, final int dirtyBits) throws SQLException
@@ -347,9 +349,9 @@ else if (dataSourceJNDI != null && ds == null) {
/**
* Obtain connection from data source.
*
- * @return a Connection connection
+ * @return a Connection
*/
- private Connection newConnection() throws Exception
+ private Connection newConnection(final boolean isEmptyPool) throws Exception
{
final var start = currentTime();
final var id = java.util.UUID.randomUUID();
@@ -360,24 +362,32 @@ private Connection newConnection() throws Exception
final var username = credentials.getUsername();
final var password = credentials.getPassword();
- logger.debug("{} - Attempting to create/setup new connection: {} ", poolName, id.toString());
-
+ logger.debug("{} - Attempting to create/setup new connection ({})", poolName, id);
+
connection = (username == null) ? dataSource.getConnection() : dataSource.getConnection(username, password);
if (connection == null) {
throw new SQLTransientConnectionException("DataSource returned null unexpectedly");
}
setupConnection(connection);
- logger.debug("{} - Established new connection: {}", poolName, id);
+
lastConnectionFailure.set(null);
+ connectionFailureTimestamp.set(0);
+
+ logger.debug("{} - Established new connection ({})", poolName, id);
return connection;
}
catch (Exception e) {
- if (connection != null) {
- quietlyCloseConnection(connection, "(Failed to create/setup connection for id:".concat(id.toString()));
+ logger.debug("{} - Failed to create/setup connection ({}): {}", poolName, id, e.getMessage());
+
+ connectionFailureTimestamp.compareAndSet(0, start);
+ if (isEmptyPool && elapsedMillis(connectionFailureTimestamp.get()) > MINUTES.toMillis(1)) {
+ logger.warn("{} - Pool is empty, failed to create/setup connection ({})", poolName, id, e);
+ connectionFailureTimestamp.set(0);
}
- else if (getLastConnectionFailure() == null) {
- logger.debug("{} - Failed to create/setup connection: {} {}", poolName, e.getMessage(), id.toString());
+
+ if (connection != null) {
+ quietlyCloseConnection(connection, "(Failed to create/setup connection (".concat(id.toString()).concat(")"));
}
lastConnectionFailure.set(e);
@@ -392,7 +402,7 @@ else if (getLastConnectionFailure() == null) {
}
/**
- * Setup a connection initial state.
+ * Set up a connection initial state.
*
* @param connection a Connection
* @throws ConnectionSetupException thrown if any exception is encountered
@@ -634,7 +644,7 @@ private void setLoginTimeout(final DataSource dataSource)
/**
* This will create a string for debug logging. Given a set of "reset bits", this
* method will return a concatenated string, for example:
- *
+ * bag = new ConcurrentBag<>(x -> CompletableFuture.completedFuture(Boolean.TRUE))) {
assertEquals(0, bag.values(8).size());
- PoolEntry reserved = pool.newPoolEntry();
+ PoolEntry reserved = pool.newPoolEntry(false);
bag.add(reserved);
bag.reserve(reserved); // reserved
- PoolEntry inuse = pool.newPoolEntry();
+ PoolEntry inuse = pool.newPoolEntry(false);
bag.add(inuse);
bag.borrow(2, MILLISECONDS); // in use
- PoolEntry notinuse = pool.newPoolEntry();
+ PoolEntry notinuse = pool.newPoolEntry(false);
bag.add(notinuse); // not in use
bag.dumpState();
@@ -103,7 +103,7 @@ public void testConcurrentBag() throws Exception
bag.close();
try {
- PoolEntry bagEntry = pool.newPoolEntry();
+ PoolEntry bagEntry = pool.newPoolEntry(false);
bag.add(bagEntry);
assertNotEquals(bagEntry, bag.borrow(100, MILLISECONDS));
}