diff --git a/CHANGES b/CHANGES index dc72849d..559a6845 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,21 @@ Changes in 2.4.0 * Deprecated HikariDataSource.shutdown() in favor of close(). +Changes in 2.3.7 + + * Try harder at resolving the driver by various means when both driverClassName and jdbcUrl + have been specified. + + * Allow a specifically set DataSource instance to override other settings such as jdbcUrl, + dataSourceClassName, or driverClassName. + + * Fixed issue where, in the case of a driver-based configuration (jdbcUrl), we were not + initialising the network timeout Executor. + + * Fixed race condition uncovered during load-testing in which the connections in the pool + can spike to the maximum pool size when many connections reach their maxLifetime at the + same time. + Changes in 2.3.6 * Allow explicit definition of driverClassName to override DriverManager.getDriver(url) diff --git a/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java b/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java index 9a5700db..55039d30 100644 --- a/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java +++ b/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java @@ -90,16 +90,18 @@ public class ConcurrentBag implements AutoCloseab @SuppressWarnings("unchecked") public T borrow(long timeout, final TimeUnit timeUnit) throws InterruptedException { - // Try the thread-local list first - final ArrayList> list = threadList.get(); - if (list == null) { - threadList.set(new ArrayList>(16)); - } - else { - for (int i = list.size() - 1; i >= 0; i--) { - final IConcurrentBagEntry bagEntry = list.remove(i).get(); - if (bagEntry != null && bagEntry.state().compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) { - return (T) bagEntry; + if (!synchronizer.hasQueuedThreads()) { + // Try the thread-local list first + final ArrayList> list = threadList.get(); + if (list == null) { + threadList.set(new ArrayList>(16)); + } + else { + for (int i = list.size() - 1; i >= 0; i--) { + final IConcurrentBagEntry bagEntry = list.remove(i).get(); + if (bagEntry != null && bagEntry.state().compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) { + return (T) bagEntry; + } } } }