From b7a9932427da1d1903638cee494d2a9989fc2206 Mon Sep 17 00:00:00 2001 From: rusher Date: Tue, 5 Mar 2019 13:52:31 +0100 Subject: [PATCH] [CONJ-682] internal pool correction: when receiving an RST during connection validation, the pool will end up throwing connection timeout exception in place of reusing another connection. --- pom.xml | 6 +- .../jdbc/internal/util/constant/Version.java | 6 +- .../mariadb/jdbc/internal/util/pool/Pool.java | 66 ++++++++++--------- .../java/org/mariadb/jdbc/ConnectionTest.java | 2 +- src/test/resources/logback-test.xml | 2 +- 5 files changed, 44 insertions(+), 38 deletions(-) diff --git a/pom.xml b/pom.xml index f695503bf..568fb87d3 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ mariadb-java-client jar mariadb-java-client - 2.4.0 + 2.4.1-SNAPSHOT JDBC driver for MariaDB and MySQL https://mariadb.com/kb/en/mariadb/about-mariadb-connector-j/ @@ -71,8 +71,8 @@ 2.17 2 4 - 0 - + 1 + -SNAPSHOT diff --git a/src/main/java/org/mariadb/jdbc/internal/util/constant/Version.java b/src/main/java/org/mariadb/jdbc/internal/util/constant/Version.java index c837bc704..2b9af4bb6 100644 --- a/src/main/java/org/mariadb/jdbc/internal/util/constant/Version.java +++ b/src/main/java/org/mariadb/jdbc/internal/util/constant/Version.java @@ -53,9 +53,9 @@ package org.mariadb.jdbc.internal.util.constant; public final class Version { - public static final String version = "2.4.0"; + public static final String version = "2.4.1-SNAPSHOT"; public static final int majorVersion = 2; public static final int minorVersion = 4; - public static final int patchVersion = 0; - public static final String qualifier = ""; + public static final int patchVersion = 1; + public static final String qualifier = "-SNAPSHOT"; } \ No newline at end of file diff --git a/src/main/java/org/mariadb/jdbc/internal/util/pool/Pool.java b/src/main/java/org/mariadb/jdbc/internal/util/pool/Pool.java index 704d902ab..a1f1b1e31 100644 --- a/src/main/java/org/mariadb/jdbc/internal/util/pool/Pool.java +++ b/src/main/java/org/mariadb/jdbc/internal/util/pool/Pool.java @@ -257,46 +257,50 @@ private MariaDbPooledConnection getIdleConnection() throws InterruptedException private MariaDbPooledConnection getIdleConnection(long timeout, TimeUnit timeUnit) throws InterruptedException { - MariaDbPooledConnection item = - (timeout == 0) ? idleConnections.pollFirst() : idleConnections.pollFirst(timeout, timeUnit); + while (true) { + MariaDbPooledConnection item = + (timeout == 0) ? idleConnections.pollFirst() : idleConnections.pollFirst(timeout, timeUnit); - if (item != null) { - MariaDbConnection connection = item.getConnection(); - try { - if (TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - item.getLastUsed().get()) - > options.poolValidMinDelay) { + if (item != null) { + MariaDbConnection connection = item.getConnection(); + try { + if (TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - item.getLastUsed().get()) + > options.poolValidMinDelay) { + + //validate connection + if (connection.isValid(10)) { //10 seconds timeout + item.lastUsedToNow(); + return item; + } + + } else { - //validate connection - if (connection.isValid(10)) { //10 seconds timeout + // connection has been retrieved recently -> skip connection validation item.lastUsedToNow(); return item; + } - } else { + } catch (SQLException sqle) { + //eat + } - // connection has been retrieved recently -> skip connection validation - item.lastUsedToNow(); - return item; + totalConnection.decrementAndGet(); + // validation failed + silentAbortConnection(item); + addConnectionRequest(); + if (logger.isDebugEnabled()) { + logger.debug( + "pool {} connection removed from pool due to failed validation (total:{}, active:{}, pending:{})", + poolTag, totalConnection.get(), getActiveConnections(), pendingRequestNumber.get()); } - - } catch (SQLException sqle) { - //eat + continue; } - totalConnection.decrementAndGet(); + return null; - // validation failed - silentAbortConnection(item); - - if (logger.isDebugEnabled()) { - logger.debug( - "pool {} connection removed from pool due to failed validation (total:{}, active:{}, pending:{})", - poolTag, totalConnection.get(), getActiveConnections(), pendingRequestNumber.get()); - } } - - return null; } private void silentCloseConnection(MariaDbPooledConnection item) { @@ -351,10 +355,12 @@ public void connectionClosed(ConnectionEvent event) { public void connectionErrorOccurred(ConnectionEvent event) { MariaDbPooledConnection item = ((MariaDbPooledConnection) event.getSource()); - totalConnection.decrementAndGet(); + if (idleConnections.remove(item)) + totalConnection.decrementAndGet(); silentCloseConnection(item); - logger.debug("connection removed from pool {} due to having throw a Connection exception", - poolTag); + addConnectionRequest(); + logger.debug("connection {} removed from pool {} due to having throw a Connection exception (total:{}, active:{}, pending:{})", + item.getConnection().getServerThreadId(), poolTag, totalConnection.get(), getActiveConnections(), pendingRequestNumber.get()); } diff --git a/src/test/java/org/mariadb/jdbc/ConnectionTest.java b/src/test/java/org/mariadb/jdbc/ConnectionTest.java index cea2a1d57..d905ac387 100644 --- a/src/test/java/org/mariadb/jdbc/ConnectionTest.java +++ b/src/test/java/org/mariadb/jdbc/ConnectionTest.java @@ -798,7 +798,7 @@ public void testWarnings() throws SQLException { Statement stmt = sharedConnection.createStatement(); stmt.executeQuery("select now() = 1"); SQLWarning warning = sharedConnection.getWarnings(); - assertTrue(warning.getMessage().contains("Incorrect datetime value: '1'")); + assertTrue(warning.getMessage().contains("ncorrect datetime value: '1'")); sharedConnection.clearWarnings(); assertNull(sharedConnection.getWarnings()); } diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index a58102026..adf279e2c 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -60,7 +60,7 @@ - +