Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[CONJ-884] ensure pool state when connection error occurs during conn…
…ection reset
  • Loading branch information
rusher committed Jul 27, 2021
1 parent 42d1441 commit cb652bb
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 9 deletions.
5 changes: 5 additions & 0 deletions src/main/java/org/mariadb/jdbc/Connection.java
Expand Up @@ -619,6 +619,11 @@ public boolean isValid(int timeout) throws SQLException {
client.execute(PingPacket.INSTANCE);
return true;
} catch (SQLException sqle) {
if (poolConnection != null) {
MariaDbPoolConnection poolConnection = this.poolConnection;
poolConnection.fireConnectionErrorOccurred(sqle);
poolConnection.close();
}
return false;
} finally {
lock.unlock();
Expand Down
22 changes: 16 additions & 6 deletions src/main/java/org/mariadb/jdbc/pool/Pool.java
Expand Up @@ -192,15 +192,23 @@ public void connectionClosed(ConnectionEvent event) {
if (poolState.get() == POOL_STATE_OK) {
try {
if (!idleConnections.contains(item)) {
item.getConnection().setPoolConnection(null);
item.getConnection().reset();
idleConnections.addFirst(item);
item.getConnection().setPoolConnection(item);
}
} catch (SQLException sqle) {

// sql exception during reset, removing connection from pool
totalConnection.decrementAndGet();
silentCloseConnection(item.getConnection());
logger.debug("connection removed from pool {} due to error during reset", poolTag);
logger.debug(
"connection {} removed from pool {} due to error during reset (total:{}, active:{}, pending:{})",
item.getConnection().getThreadId(),
poolTag,
totalConnection.get(),
getActiveConnections(),
pendingRequestNumber.get());
}
} else {
// pool is closed, should then not be render to pool, but closed.
Expand All @@ -217,9 +225,13 @@ public void connectionClosed(ConnectionEvent event) {
public void connectionErrorOccurred(ConnectionEvent event) {

InternalPoolConnection item = ((InternalPoolConnection) event.getSource());
if (idleConnections.remove(item)) {
totalConnection.decrementAndGet();
}
totalConnection.decrementAndGet();
idleConnections.remove(item);

// ensure that other connection will be validated before being use
// since one connection failed, better to assume the other might as well
idleConnections.stream().forEach(c -> c.lastUsedToNow());

silentCloseConnection(item.getConnection());
addConnectionRequest();
logger.debug(
Expand Down Expand Up @@ -285,8 +297,6 @@ private InternalPoolConnection getIdleConnection(long timeout, TimeUnit timeUnit
// eat
}

totalConnection.decrementAndGet();

// validation failed
silentAbortConnection(item.getConnection());
addConnectionRequest();
Expand Down
Expand Up @@ -135,6 +135,7 @@ public void testPoolKillConnection() throws Exception {

try (MariaDbPoolDataSource ds =
new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=1&allowPublicKeyRetrieval")) {
Thread.sleep(100);
InternalPoolConnection pc = ds.getPooledConnection();
org.mariadb.jdbc.Connection conn = pc.getConnection();
long threadId = conn.getThreadId();
Expand All @@ -153,10 +154,12 @@ public void testPoolKillConnection() throws Exception {
String contents = new String(Files.readAllBytes(Paths.get(tempFile.getPath())));
assertTrue(
contents.contains(
"removed from pool MariaDB-pool due to having throw a Connection exception (total:1, active:1, pending:0)"));
"removed from pool MariaDB-pool due to error during reset (total:0, active:0, pending:0)"),
contents);
assertTrue(contents.contains("pool MariaDB-pool new physical connection created"), contents);

assertTrue(
contents.contains("connection removed from pool MariaDB-pool due to error during reset"));
assertTrue(contents.contains("closing pool MariaDB-pool (total:1, active:0, pending:0)"));
contents.contains("closing pool MariaDB-pool (total:1, active:0, pending:0)"), contents);
logger.setLevel(initialLevel);
logger.detachAppender(fa);
}
Expand Down

0 comments on commit cb652bb

Please sign in to comment.