From aa9ee1eddf488c9967429a7daafb0b082c8b5f30 Mon Sep 17 00:00:00 2001 From: Deeptanshu-Chowdhuri Date: Mon, 29 May 2023 13:21:04 +0530 Subject: [PATCH 01/19] Done begin and endRequest. --- src/main/java/com/zaxxer/hikari/pool/HikariPool.java | 11 +++++++++-- .../java/com/zaxxer/hikari/pool/ProxyConnection.java | 6 ++++++ .../java/com/zaxxer/hikari/util/ConcurrentBag.java | 1 + .../java/com/zaxxer/hikari/util/DriverDataSource.java | 3 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java index 077120551..64af51cc4 100644 --- a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java +++ b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java @@ -155,7 +155,7 @@ public Connection getConnection(final long hardTimeout) throws SQLException { suspendResumeLock.acquire(); final var startTime = currentTime(); - +// Connectio Borrowed here try { var timeout = hardTimeout; do { @@ -171,7 +171,14 @@ public Connection getConnection(final long hardTimeout) throws SQLException } else { metricsTracker.recordBorrowStats(poolEntry, startTime); - return poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry)); + Connection newconn=poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry)); + if (newconn.getMetaData().getJDBCMajorVersion()>4 || + (newconn.getMetaData().getJDBCMajorVersion()==4 && newconn.getMetaData().getJDBCMinorVersion()>=3)) { + newconn.beginRequest(); + System.out.println("BEGIN REQUEST CALLED"); + } +// return poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry)); + return newconn; } } while (timeout > 0L); diff --git a/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java b/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java index 8b6701adf..999d3dacd 100644 --- a/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java +++ b/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java @@ -264,8 +264,14 @@ public final void close() throws SQLException } } finally { + if (delegate.getMetaData().getJDBCMajorVersion()>4 || + (delegate.getMetaData().getJDBCMajorVersion()==4 && delegate.getMetaData().getJDBCMinorVersion()>=3)) { + delegate.endRequest(); + System.out.println("END REQUEST CALLED"); + } delegate = ClosedConnection.CLOSED_CONNECTION; poolEntry.recycle(); +// MAybe here connection is sent back } } } diff --git a/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java b/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java index 95dab9e37..4f60a1150 100644 --- a/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java +++ b/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java @@ -120,6 +120,7 @@ public ConcurrentBag(final IBagStateListener listener) public T borrow(long timeout, final TimeUnit timeUnit) throws InterruptedException { // Try the thread-local list first +// Try to get and mark the connection final var list = threadList.get(); for (int i = list.size() - 1; i >= 0; i--) { final var entry = list.remove(i); diff --git a/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java b/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java index ce5291cd2..d8dc41e4d 100644 --- a/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java +++ b/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java @@ -99,7 +99,7 @@ public DriverDataSource(String jdbcUrl, String driverClassName, Properties prope } final var sanitizedUrl = jdbcUrl.replaceAll("([?&;][^&#;=]*[pP]assword=)[^&#;]*", "$1"); - + try { if (driver == null) { driver = DriverManager.getDriver(jdbcUrl); @@ -133,6 +133,7 @@ public Connection getConnection(final String username, final String password) th if (password != null) { cloned.put(PASSWORD, password); } +// maybe here connection is pulled return driver.connect(jdbcUrl, cloned); } From 9c3f087b4cfffbe8338726a9041ee29432f8d01f Mon Sep 17 00:00:00 2001 From: Deeptanshu-Chowdhuri Date: Tue, 30 May 2023 11:16:26 +0530 Subject: [PATCH 02/19] BeginRequest Changed a bit. --- .../com/zaxxer/hikari/pool/HikariPool.java | 17 +++++++++++---- .../zaxxer/hikari/pool/ProxyConnection.java | 21 +++++++++++++------ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java index 64af51cc4..d2d6856d1 100644 --- a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java +++ b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java @@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory; import java.sql.Connection; +import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.sql.SQLTransientConnectionException; import java.util.Optional; @@ -172,10 +173,18 @@ public Connection getConnection(final long hardTimeout) throws SQLException else { metricsTracker.recordBorrowStats(poolEntry, startTime); Connection newconn=poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry)); - if (newconn.getMetaData().getJDBCMajorVersion()>4 || - (newconn.getMetaData().getJDBCMajorVersion()==4 && newconn.getMetaData().getJDBCMinorVersion()>=3)) { - newconn.beginRequest(); - System.out.println("BEGIN REQUEST CALLED"); + DatabaseMetaData dm= newconn.getMetaData(); + if (dm!=null){ + try { + if (dm.getJDBCMajorVersion() > 4 || + (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3)) { + newconn.beginRequest(); + System.out.println("BEGIN REQUEST CALLED"); + } + } + catch(NullPointerException np){ + System.out.println("getJDBCMajorVersion Call Failed"); + } } // return poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry)); return newconn; diff --git a/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java b/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java index 999d3dacd..193948a92 100644 --- a/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java +++ b/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java @@ -104,6 +104,7 @@ public final String toString() return this.getClass().getSimpleName() + '@' + System.identityHashCode(this) + " wrapping " + delegate; } + // *********************************************************************** // Connection State Accessors // *********************************************************************** @@ -264,13 +265,21 @@ public final void close() throws SQLException } } finally { - if (delegate.getMetaData().getJDBCMajorVersion()>4 || - (delegate.getMetaData().getJDBCMajorVersion()==4 && delegate.getMetaData().getJDBCMinorVersion()>=3)) { - delegate.endRequest(); - System.out.println("END REQUEST CALLED"); + DatabaseMetaData dm= delegate.getMetaData(); + if (dm!=null){ + if (delegate.getMetaData().getJDBCMajorVersion() > 4 || + (delegate.getMetaData().getJDBCMajorVersion() == 4 && delegate.getMetaData().getJDBCMinorVersion() >= 3)) { + delegate.endRequest(); + System.out.println("END REQUEST CALLED"); + } + delegate = ClosedConnection.CLOSED_CONNECTION; + poolEntry.recycle(); } - delegate = ClosedConnection.CLOSED_CONNECTION; - poolEntry.recycle(); + else{ + delegate = ClosedConnection.CLOSED_CONNECTION; + poolEntry.recycle(); + } + // MAybe here connection is sent back } } From 06504568fc31690a68111607e57c2ceb7fc0480b Mon Sep 17 00:00:00 2001 From: Deeptanshu-Chowdhuri Date: Wed, 31 May 2023 10:30:09 +0530 Subject: [PATCH 03/19] Pool Entry changed only --- .../com/zaxxer/hikari/pool/HikariPool.java | 20 ++----------- .../com/zaxxer/hikari/pool/PoolEntry.java | 29 ++++++++++++++++--- .../zaxxer/hikari/pool/ProxyConnection.java | 18 ++---------- 3 files changed, 29 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java index d2d6856d1..077120551 100644 --- a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java +++ b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java @@ -33,7 +33,6 @@ import org.slf4j.LoggerFactory; import java.sql.Connection; -import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.sql.SQLTransientConnectionException; import java.util.Optional; @@ -156,7 +155,7 @@ public Connection getConnection(final long hardTimeout) throws SQLException { suspendResumeLock.acquire(); final var startTime = currentTime(); -// Connectio Borrowed here + try { var timeout = hardTimeout; do { @@ -172,22 +171,7 @@ public Connection getConnection(final long hardTimeout) throws SQLException } else { metricsTracker.recordBorrowStats(poolEntry, startTime); - Connection newconn=poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry)); - DatabaseMetaData dm= newconn.getMetaData(); - if (dm!=null){ - try { - if (dm.getJDBCMajorVersion() > 4 || - (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3)) { - newconn.beginRequest(); - System.out.println("BEGIN REQUEST CALLED"); - } - } - catch(NullPointerException np){ - System.out.println("getJDBCMajorVersion Call Failed"); - } - } -// return poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry)); - return newconn; + return poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry)); } } while (timeout > 0L); diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java index a2392b913..3a3a95a09 100644 --- a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java +++ b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java @@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory; import java.sql.Connection; +import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.concurrent.ScheduledFuture; @@ -74,10 +75,20 @@ final class PoolEntry implements IConcurrentBagEntry /** * Release this entry back to the pool. */ - void recycle() - { + void recycle() throws SQLException { + // endRequest Call just to let driver know.support only for jdbc4.3 and above if (connection != null) { this.lastAccessed = currentTime(); + DatabaseMetaData dm= connection.getMetaData(); + if (dm!=null){ + if (dm.getJDBCMajorVersion() > 4 || + (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3)) { + connection.endRequest(); + } + } + else{ + LOGGER.warn("endRequest cannot be called as getMetaData not found for Connection: {}", connection); + } hikariPool.recycle(this); } } @@ -96,8 +107,18 @@ public void setKeepalive(ScheduledFuture keepalive) { this.keepalive = keepalive; } - Connection createProxyConnection(final ProxyLeakTask leakTask) - { + Connection createProxyConnection(final ProxyLeakTask leakTask) throws SQLException { + DatabaseMetaData dm= connection.getMetaData(); + // calling beginRequest for JDBC 4.3 and later + if (dm!=null){ + if (dm.getJDBCMajorVersion() > 4 || + (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3)) { + connection.beginRequest(); + } + } + else{ + LOGGER.warn("beginRequest cannot be called as getMetaData not found for Connection: {}", connection); + } return ProxyFactory.getProxyConnection(this, connection, openStatements, leakTask, isReadOnly, isAutoCommit); } diff --git a/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java b/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java index 193948a92..a23936b84 100644 --- a/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java +++ b/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java @@ -265,22 +265,8 @@ public final void close() throws SQLException } } finally { - DatabaseMetaData dm= delegate.getMetaData(); - if (dm!=null){ - if (delegate.getMetaData().getJDBCMajorVersion() > 4 || - (delegate.getMetaData().getJDBCMajorVersion() == 4 && delegate.getMetaData().getJDBCMinorVersion() >= 3)) { - delegate.endRequest(); - System.out.println("END REQUEST CALLED"); - } - delegate = ClosedConnection.CLOSED_CONNECTION; - poolEntry.recycle(); - } - else{ - delegate = ClosedConnection.CLOSED_CONNECTION; - poolEntry.recycle(); - } - -// MAybe here connection is sent back + delegate = ClosedConnection.CLOSED_CONNECTION; + poolEntry.recycle(); } } } From 5d5b6e670ffeb3775b17ae80bdf4c1ed70dcf503 Mon Sep 17 00:00:00 2001 From: Deeptanshu-Chowdhuri Date: Wed, 31 May 2023 10:44:01 +0530 Subject: [PATCH 04/19] Removed Useless Comments --- src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java | 1 - src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java | 1 - src/main/java/com/zaxxer/hikari/util/DriverDataSource.java | 2 -- 3 files changed, 4 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java b/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java index a23936b84..8b6701adf 100644 --- a/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java +++ b/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java @@ -104,7 +104,6 @@ public final String toString() return this.getClass().getSimpleName() + '@' + System.identityHashCode(this) + " wrapping " + delegate; } - // *********************************************************************** // Connection State Accessors // *********************************************************************** diff --git a/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java b/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java index 4f60a1150..95dab9e37 100644 --- a/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java +++ b/src/main/java/com/zaxxer/hikari/util/ConcurrentBag.java @@ -120,7 +120,6 @@ public ConcurrentBag(final IBagStateListener listener) public T borrow(long timeout, final TimeUnit timeUnit) throws InterruptedException { // Try the thread-local list first -// Try to get and mark the connection final var list = threadList.get(); for (int i = list.size() - 1; i >= 0; i--) { final var entry = list.remove(i); diff --git a/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java b/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java index d8dc41e4d..0118b9cf7 100644 --- a/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java +++ b/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java @@ -99,7 +99,6 @@ public DriverDataSource(String jdbcUrl, String driverClassName, Properties prope } final var sanitizedUrl = jdbcUrl.replaceAll("([?&;][^&#;=]*[pP]assword=)[^&#;]*", "$1"); - try { if (driver == null) { driver = DriverManager.getDriver(jdbcUrl); @@ -133,7 +132,6 @@ public Connection getConnection(final String username, final String password) th if (password != null) { cloned.put(PASSWORD, password); } -// maybe here connection is pulled return driver.connect(jdbcUrl, cloned); } From eed24d2b03444d582055e69548b0212557e5e7cb Mon Sep 17 00:00:00 2001 From: Deeptanshu-Chowdhuri Date: Wed, 31 May 2023 14:59:25 +0530 Subject: [PATCH 05/19] Added Try catch to avoid changing function signature and stop at begin or endRequest. --- .../com/zaxxer/hikari/pool/PoolEntry.java | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java index 3a3a95a09..4e6ee9cda 100644 --- a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java +++ b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java @@ -75,19 +75,20 @@ final class PoolEntry implements IConcurrentBagEntry /** * Release this entry back to the pool. */ - void recycle() throws SQLException { - // endRequest Call just to let driver know.support only for jdbc4.3 and above + void recycle() { + // endRequest Call just to let driver know.Supported only for JDBC 4.3 and above if (connection != null) { this.lastAccessed = currentTime(); - DatabaseMetaData dm= connection.getMetaData(); - if (dm!=null){ - if (dm.getJDBCMajorVersion() > 4 || - (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3)) { - connection.endRequest(); + try { + DatabaseMetaData dm = connection.getMetaData(); + if (dm!=null){ + if (dm.getJDBCMajorVersion() > 4 || + (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3)) { + connection.endRequest(); + } } - } - else{ - LOGGER.warn("endRequest cannot be called as getMetaData not found for Connection: {}", connection); + } catch (SQLException e) { + LOGGER.warn("{},endRequest Failed: {}",e,connection); } hikariPool.recycle(this); } @@ -107,19 +108,21 @@ public void setKeepalive(ScheduledFuture keepalive) { this.keepalive = keepalive; } - Connection createProxyConnection(final ProxyLeakTask leakTask) throws SQLException { - DatabaseMetaData dm= connection.getMetaData(); + Connection createProxyConnection(final ProxyLeakTask leakTask){ + Connection newproxyconn= ProxyFactory.getProxyConnection(this, connection, openStatements, leakTask, isReadOnly, isAutoCommit); // calling beginRequest for JDBC 4.3 and later - if (dm!=null){ - if (dm.getJDBCMajorVersion() > 4 || - (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3)) { - connection.beginRequest(); + try { + DatabaseMetaData dm=connection.getMetaData(); + if (dm!=null){ + if (dm.getJDBCMajorVersion() > 4 || + (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3)) { + connection.beginRequest(); + } } + } catch (SQLException e) { + LOGGER.warn("{},beginRequest Failed: {}",e,connection); } - else{ - LOGGER.warn("beginRequest cannot be called as getMetaData not found for Connection: {}", connection); - } - return ProxyFactory.getProxyConnection(this, connection, openStatements, leakTask, isReadOnly, isAutoCommit); + return newproxyconn; } void resetConnectionState(final ProxyConnection proxyConnection, final int dirtyBits) throws SQLException From a8e905e7d9079936e1c3b0d8f1aa780baf892c27 Mon Sep 17 00:00:00 2001 From: Deeptanshu-Chowdhuri Date: Wed, 31 May 2023 15:09:44 +0530 Subject: [PATCH 06/19] changed Log warning for begin and endRequest --- src/main/java/com/zaxxer/hikari/pool/PoolEntry.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java index 4e6ee9cda..86d51c9a4 100644 --- a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java +++ b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java @@ -88,7 +88,7 @@ void recycle() { } } } catch (SQLException e) { - LOGGER.warn("{},endRequest Failed: {}",e,connection); + LOGGER.warn("endRequest Failed for: {},({})",connection,e.getMessage()); } hikariPool.recycle(this); } @@ -120,7 +120,7 @@ Connection createProxyConnection(final ProxyLeakTask leakTask){ } } } catch (SQLException e) { - LOGGER.warn("{},beginRequest Failed: {}",e,connection); + LOGGER.warn("beginRequest Failed for: {}, ({})",connection,e.getMessage()); } return newproxyconn; } From 248bc3b6702988da75bad06175005286a7dffa8f Mon Sep 17 00:00:00 2001 From: Deeptanshu-Chowdhuri Date: Wed, 31 May 2023 17:32:39 +0530 Subject: [PATCH 07/19] changed Formatting and commented changes. --- src/main/java/com/zaxxer/hikari/pool/PoolEntry.java | 12 ++++++++---- .../com/zaxxer/hikari/util/DriverDataSource.java | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java index 86d51c9a4..beab67aba 100644 --- a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java +++ b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java @@ -75,8 +75,10 @@ final class PoolEntry implements IConcurrentBagEntry /** * Release this entry back to the pool. */ - void recycle() { - // endRequest Call just to let driver know.Supported only for JDBC 4.3 and above + void recycle() + { + // endRequest Call just to let driver know that the connection has been returned to pool. + // Supported only for JDBC 4.3 and above if (connection != null) { this.lastAccessed = currentTime(); try { @@ -108,9 +110,11 @@ public void setKeepalive(ScheduledFuture keepalive) { this.keepalive = keepalive; } - Connection createProxyConnection(final ProxyLeakTask leakTask){ + Connection createProxyConnection(final ProxyLeakTask leakTask) + { Connection newproxyconn= ProxyFactory.getProxyConnection(this, connection, openStatements, leakTask, isReadOnly, isAutoCommit); - // calling beginRequest for JDBC 4.3 and later + // beginRequest Call just to let driver know that the connection has been borrowed from the pool. + // Supported only for JDBC 4.3 and above try { DatabaseMetaData dm=connection.getMetaData(); if (dm!=null){ diff --git a/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java b/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java index 0118b9cf7..a72de56d0 100644 --- a/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java +++ b/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java @@ -99,6 +99,7 @@ public DriverDataSource(String jdbcUrl, String driverClassName, Properties prope } final var sanitizedUrl = jdbcUrl.replaceAll("([?&;][^&#;=]*[pP]assword=)[^&#;]*", "$1"); + try { if (driver == null) { driver = DriverManager.getDriver(jdbcUrl); From 726876fe4b1dcd4b83dc235dfd22388726dcf43c Mon Sep 17 00:00:00 2001 From: Deeptanshu-Chowdhuri Date: Wed, 31 May 2023 19:57:38 +0530 Subject: [PATCH 08/19] corrected DriverDataSource.java --- src/main/java/com/zaxxer/hikari/util/DriverDataSource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java b/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java index a72de56d0..ce5291cd2 100644 --- a/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java +++ b/src/main/java/com/zaxxer/hikari/util/DriverDataSource.java @@ -99,7 +99,7 @@ public DriverDataSource(String jdbcUrl, String driverClassName, Properties prope } final var sanitizedUrl = jdbcUrl.replaceAll("([?&;][^&#;=]*[pP]assword=)[^&#;]*", "$1"); - + try { if (driver == null) { driver = DriverManager.getDriver(jdbcUrl); From b21683cd191a1c8eeb39e2a49167c2f44b826f90 Mon Sep 17 00:00:00 2001 From: Deeptanshu-Chowdhuri Date: Fri, 7 Jul 2023 15:40:18 +0530 Subject: [PATCH 09/19] Removed comments to comply with the repository. --- src/main/java/com/zaxxer/hikari/pool/PoolEntry.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java index beab67aba..32fcf268a 100644 --- a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java +++ b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java @@ -77,8 +77,6 @@ final class PoolEntry implements IConcurrentBagEntry */ void recycle() { - // endRequest Call just to let driver know that the connection has been returned to pool. - // Supported only for JDBC 4.3 and above if (connection != null) { this.lastAccessed = currentTime(); try { @@ -113,8 +111,6 @@ public void setKeepalive(ScheduledFuture keepalive) { Connection createProxyConnection(final ProxyLeakTask leakTask) { Connection newproxyconn= ProxyFactory.getProxyConnection(this, connection, openStatements, leakTask, isReadOnly, isAutoCommit); - // beginRequest Call just to let driver know that the connection has been borrowed from the pool. - // Supported only for JDBC 4.3 and above try { DatabaseMetaData dm=connection.getMetaData(); if (dm!=null){ From df4bfcedb0078126fcdfac05dbad946110ec6efb Mon Sep 17 00:00:00 2001 From: Fernanda Meheust Date: Tue, 24 Oct 2023 10:37:58 +0200 Subject: [PATCH 10/19] Moved get JDBCVersion --- .../com/zaxxer/hikari/pool/PoolEntry.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java index 32fcf268a..a1c702171 100644 --- a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java +++ b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java @@ -56,6 +56,7 @@ final class PoolEntry implements IConcurrentBagEntry private final boolean isReadOnly; private final boolean isAutoCommit; + private boolean isJDBC43OrLater; static { @@ -70,6 +71,17 @@ final class PoolEntry implements IConcurrentBagEntry this.isAutoCommit = isAutoCommit; this.lastAccessed = currentTime(); this.openStatements = new FastList<>(Statement.class, 16); + boolean isJDBC43OrLater = false; + try { + DatabaseMetaData dm = connection.getMetaData(); + isJDBC43OrLater = ((dm != null) && ( + (dm.getJDBCMajorVersion() > 4) || + (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3) + )); + } catch (SQLException sqlEx) { + LOGGER.warn("getMetaData Failed for: {},({})", connection, sqlEx.getMessage()); + } + this.isJDBC43OrLater = isJDBC43OrLater; } /** @@ -80,12 +92,8 @@ void recycle() if (connection != null) { this.lastAccessed = currentTime(); try { - DatabaseMetaData dm = connection.getMetaData(); - if (dm!=null){ - if (dm.getJDBCMajorVersion() > 4 || - (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3)) { - connection.endRequest(); - } + if (this.isJDBC43OrLater){ + connection.endRequest(); } } catch (SQLException e) { LOGGER.warn("endRequest Failed for: {},({})",connection,e.getMessage()); @@ -112,12 +120,8 @@ Connection createProxyConnection(final ProxyLeakTask leakTask) { Connection newproxyconn= ProxyFactory.getProxyConnection(this, connection, openStatements, leakTask, isReadOnly, isAutoCommit); try { - DatabaseMetaData dm=connection.getMetaData(); - if (dm!=null){ - if (dm.getJDBCMajorVersion() > 4 || - (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3)) { - connection.beginRequest(); - } + if (this.isJDBC43OrLater){ + connection.beginRequest(); } } catch (SQLException e) { LOGGER.warn("beginRequest Failed for: {}, ({})",connection,e.getMessage()); From 116e3babfa126464c0d6bab34b8ac1fc90fa6672 Mon Sep 17 00:00:00 2001 From: Fernanda Meheust Date: Tue, 24 Oct 2023 12:05:19 +0200 Subject: [PATCH 11/19] PoolEntry begin end request test --- .../com/zaxxer/hikari/pool/PoolEntryTest.java | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/test/java/com/zaxxer/hikari/pool/PoolEntryTest.java diff --git a/src/test/java/com/zaxxer/hikari/pool/PoolEntryTest.java b/src/test/java/com/zaxxer/hikari/pool/PoolEntryTest.java new file mode 100644 index 000000000..ba50879b6 --- /dev/null +++ b/src/test/java/com/zaxxer/hikari/pool/PoolEntryTest.java @@ -0,0 +1,105 @@ +package com.zaxxer.hikari.pool; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariConfigTest; +import com.zaxxer.hikari.HikariDataSource; +import com.zaxxer.hikari.mocks.StubDataSource; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; + +import static com.zaxxer.hikari.pool.TestElf.getPool; +import static com.zaxxer.hikari.pool.TestElf.newHikariConfig; + +public class PoolEntryTest { + + private static final HikariPool poolBase; + static { + HikariConfig config = newHikariConfig(); + config.setMinimumIdle(0); + config.setMaximumPoolSize(10); + config.setInitializationFailTimeout(Long.MAX_VALUE); + config.setConnectionTestQuery("VALUES 1"); + config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); + HikariDataSource ds = new HikariDataSource(config); + poolBase = getPool(ds); + } + + private Connection getConnection(int major, int minor) throws Exception { + DatabaseMetaData databaseMetaData = Mockito.mock(DatabaseMetaData.class); + Mockito.when(databaseMetaData.getJDBCMajorVersion()).thenReturn(major); + Mockito.when(databaseMetaData.getJDBCMinorVersion()).thenReturn(minor); + Connection connection = Mockito.mock(Connection.class); + Mockito.when(connection.getMetaData()).thenReturn(databaseMetaData); + return connection; + } + + @Test + public void BeginEndRequestJDBC42Test() throws Exception { + Connection connection = getConnection(4,2); + PoolEntry poolEntry = new PoolEntry(connection, poolBase, false, false); + Connection proxyConnection = poolEntry.createProxyConnection(ProxyLeakTask.NO_LEAK); + Mockito.verify(connection, Mockito.never()).beginRequest(); + Mockito.verify(connection, Mockito.never()).endRequest(); + poolEntry.recycle(); + Mockito.verify(connection, Mockito.never()).beginRequest(); + Mockito.verify(connection, Mockito.never()).endRequest(); + Mockito.verify(connection, Mockitp.atMostOnce()).getMetaData(); + } + + @Test + public void BeginEndRequestJDBC38Test() throws Exception { + Connection connection = getConnection(3,8); + PoolEntry poolEntry = new PoolEntry(connection, poolBase, false, false); + Connection proxyConnection = poolEntry.createProxyConnection(ProxyLeakTask.NO_LEAK); + Mockito.verify(connection, Mockito.never()).beginRequest(); + Mockito.verify(connection, Mockito.never()).endRequest(); + poolEntry.recycle(); + Mockito.verify(connection, Mockito.never()).beginRequest(); + Mockito.verify(connection, Mockito.never()).endRequest(); + Mockito.verify(connection, Mockitp.atMostOnce()).getMetaData(); + } + + @Test + public void BeginEndRequestJDBC43Test() throws Exception { + Connection connection = getConnection(4,3); + PoolEntry poolEntry = new PoolEntry(connection, poolBase, false, false); + Connection proxyConnection = poolEntry.createProxyConnection(ProxyLeakTask.NO_LEAK); + Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); + Mockito.verify(connection, Mockito.never()).endRequest(); + poolEntry.recycle(); + Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); + Mockito.verify(connection, Mockito.atMostOnce()).endRequest(); + Mockito.verify(connection, Mockitp.atMostOnce()).getMetaData(); + } + + @Test + public void BeginEndRequestJDBC47Test() throws Exception { + Connection connection = getConnection(4,7); + PoolEntry poolEntry = new PoolEntry(connection, poolBase, false, false); + Connection proxyConnection = poolEntry.createProxyConnection(ProxyLeakTask.NO_LEAK); + Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); + Mockito.verify(connection, Mockito.never()).endRequest(); + poolEntry.recycle(); + Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); + Mockito.verify(connection, Mockito.atMostOnce()).endRequest(); + Mockito.verify(connection, Mockitp.atMostOnce()).getMetaData(); + } + + @Test + public void BeginEndRequestJDBC50Test() throws Exception { + Connection connection = getConnection(5,0); + PoolEntry poolEntry = new PoolEntry(connection, poolBase, false, false); + Connection proxyConnection = poolEntry.createProxyConnection(ProxyLeakTask.NO_LEAK); + Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); + Mockito.verify(connection, Mockito.never()).endRequest(); + poolEntry.recycle(); + Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); + Mockito.verify(connection, Mockito.atMostOnce()).endRequest(); + Mockito.verify(connection, Mockitp.atMostOnce()).getMetaData(); + } + +} From 0b35a72d068f363597fba6ef177f241f2abfe652 Mon Sep 17 00:00:00 2001 From: Fernanda Meheust Date: Tue, 24 Oct 2023 12:06:36 +0200 Subject: [PATCH 12/19] typo --- .../java/com/zaxxer/hikari/pool/PoolEntryTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/zaxxer/hikari/pool/PoolEntryTest.java b/src/test/java/com/zaxxer/hikari/pool/PoolEntryTest.java index ba50879b6..0341482c2 100644 --- a/src/test/java/com/zaxxer/hikari/pool/PoolEntryTest.java +++ b/src/test/java/com/zaxxer/hikari/pool/PoolEntryTest.java @@ -47,7 +47,7 @@ public void BeginEndRequestJDBC42Test() throws Exception { poolEntry.recycle(); Mockito.verify(connection, Mockito.never()).beginRequest(); Mockito.verify(connection, Mockito.never()).endRequest(); - Mockito.verify(connection, Mockitp.atMostOnce()).getMetaData(); + Mockito.verify(connection, Mockito.atMostOnce()).getMetaData(); } @Test @@ -60,7 +60,7 @@ public void BeginEndRequestJDBC38Test() throws Exception { poolEntry.recycle(); Mockito.verify(connection, Mockito.never()).beginRequest(); Mockito.verify(connection, Mockito.never()).endRequest(); - Mockito.verify(connection, Mockitp.atMostOnce()).getMetaData(); + Mockito.verify(connection, Mockito.atMostOnce()).getMetaData(); } @Test @@ -73,7 +73,7 @@ public void BeginEndRequestJDBC43Test() throws Exception { poolEntry.recycle(); Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); Mockito.verify(connection, Mockito.atMostOnce()).endRequest(); - Mockito.verify(connection, Mockitp.atMostOnce()).getMetaData(); + Mockito.verify(connection, Mockito.atMostOnce()).getMetaData(); } @Test @@ -86,7 +86,7 @@ public void BeginEndRequestJDBC47Test() throws Exception { poolEntry.recycle(); Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); Mockito.verify(connection, Mockito.atMostOnce()).endRequest(); - Mockito.verify(connection, Mockitp.atMostOnce()).getMetaData(); + Mockito.verify(connection, Mockito.atMostOnce()).getMetaData(); } @Test @@ -99,7 +99,7 @@ public void BeginEndRequestJDBC50Test() throws Exception { poolEntry.recycle(); Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); Mockito.verify(connection, Mockito.atMostOnce()).endRequest(); - Mockito.verify(connection, Mockitp.atMostOnce()).getMetaData(); + Mockito.verify(connection, Mockito.atMostOnce()).getMetaData(); } } From 2b9a35c4711305e71af9cf293fd95ba9fa9d0b56 Mon Sep 17 00:00:00 2001 From: Fernanda Meheust Date: Mon, 30 Oct 2023 20:02:51 +0100 Subject: [PATCH 13/19] Moved request boundaries to HikariPool + property --- .../com/zaxxer/hikari/pool/HikariPool.java | 15 +++ .../com/zaxxer/hikari/pool/PoolEntry.java | 20 +--- .../zaxxer/hikari/mocks/StubConnection.java | 13 +++ .../com/zaxxer/hikari/pool/PoolEntryTest.java | 105 ------------------ .../hikari/pool/RequestBoundaryTest.java | 57 ++++++++++ 5 files changed, 88 insertions(+), 122 deletions(-) delete mode 100644 src/test/java/com/zaxxer/hikari/pool/PoolEntryTest.java create mode 100644 src/test/java/com/zaxxer/hikari/pool/RequestBoundaryTest.java diff --git a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java index 077120551..64e16b63b 100644 --- a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java +++ b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java @@ -64,6 +64,7 @@ public final class HikariPool extends PoolBase implements HikariPoolMXBean, IBag private final long aliveBypassWindowMs = Long.getLong("com.zaxxer.hikari.aliveBypassWindowMs", MILLISECONDS.toMillis(500)); private final long housekeepingPeriodMs = Long.getLong("com.zaxxer.hikari.housekeeping.periodMs", SECONDS.toMillis(30)); + private final boolean isRequestBoundariesEnabled = Boolean.getBoolean("com.zaxxer.hikari.enableRequestBoundary"); private static final String EVICTED_CONNECTION_MESSAGE = "(connection was evicted)"; private static final String DEAD_CONNECTION_MESSAGE = "(connection is dead)"; @@ -171,6 +172,13 @@ public Connection getConnection(final long hardTimeout) throws SQLException } else { metricsTracker.recordBorrowStats(poolEntry, startTime); + try { + if (isRequestBoundariesEnabled) { + poolEntry.connection.beginRequest(); + } + } catch (SQLException e) { + logger.warn("beginRequest Failed for: {}, ({})", poolEntry.connection, e.getMessage()); + } return poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry)); } } while (timeout > 0L); @@ -416,6 +424,13 @@ void logPoolState(String... prefix) @Override void recycle(final PoolEntry poolEntry) { + try { + if (isRequestBoundariesEnabled) { + poolEntry.connection.endRequest(); + } + } catch (SQLException e) { + logger.warn("endRequest Failed for: {},({})", poolEntry.connection, e.getMessage()); + } metricsTracker.recordConnectionUsage(poolEntry); connectionBag.requite(poolEntry); diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java index a1c702171..38c1fed0f 100644 --- a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java +++ b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java @@ -75,7 +75,7 @@ final class PoolEntry implements IConcurrentBagEntry try { DatabaseMetaData dm = connection.getMetaData(); isJDBC43OrLater = ((dm != null) && ( - (dm.getJDBCMajorVersion() > 4) || + (dm.getJDBCMajorVersion() > 4) || (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3) )); } catch (SQLException sqlEx) { @@ -91,13 +91,7 @@ void recycle() { if (connection != null) { this.lastAccessed = currentTime(); - try { - if (this.isJDBC43OrLater){ - connection.endRequest(); - } - } catch (SQLException e) { - LOGGER.warn("endRequest Failed for: {},({})",connection,e.getMessage()); - } + hikariPool.recycle(this); } } @@ -118,15 +112,7 @@ public void setKeepalive(ScheduledFuture keepalive) { Connection createProxyConnection(final ProxyLeakTask leakTask) { - Connection newproxyconn= ProxyFactory.getProxyConnection(this, connection, openStatements, leakTask, isReadOnly, isAutoCommit); - try { - if (this.isJDBC43OrLater){ - connection.beginRequest(); - } - } catch (SQLException e) { - LOGGER.warn("beginRequest Failed for: {}, ({})",connection,e.getMessage()); - } - return newproxyconn; + return ProxyFactory.getProxyConnection(this, connection, openStatements, leakTask, isReadOnly, isAutoCommit); } void resetConnectionState(final ProxyConnection proxyConnection, final int dirtyBits) throws SQLException diff --git a/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java b/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java index 8d7bc4292..47ce19232 100644 --- a/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java +++ b/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java @@ -59,6 +59,9 @@ public class StubConnection extends StubBaseConnection private static ScheduledExecutorService connectionWaitTimeout = new ScheduledThreadPoolExecutor(1); private ScheduledFuture waitTimeoutTask; + public boolean beginRequestCalled = false; + public boolean endRequestCalled = false; + static { foo = System.currentTimeMillis(); } @@ -530,4 +533,14 @@ public int getNetworkTimeout() throws SQLException return 0; } + @Override + public void beginRequest() { + beginRequestCalled = true; + } + + @Override + public void endRequest() { + endRequestCalled = true; + } + } diff --git a/src/test/java/com/zaxxer/hikari/pool/PoolEntryTest.java b/src/test/java/com/zaxxer/hikari/pool/PoolEntryTest.java deleted file mode 100644 index 0341482c2..000000000 --- a/src/test/java/com/zaxxer/hikari/pool/PoolEntryTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.zaxxer.hikari.pool; - -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariConfigTest; -import com.zaxxer.hikari.HikariDataSource; -import com.zaxxer.hikari.mocks.StubDataSource; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; - -import static com.zaxxer.hikari.pool.TestElf.getPool; -import static com.zaxxer.hikari.pool.TestElf.newHikariConfig; - -public class PoolEntryTest { - - private static final HikariPool poolBase; - static { - HikariConfig config = newHikariConfig(); - config.setMinimumIdle(0); - config.setMaximumPoolSize(10); - config.setInitializationFailTimeout(Long.MAX_VALUE); - config.setConnectionTestQuery("VALUES 1"); - config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); - HikariDataSource ds = new HikariDataSource(config); - poolBase = getPool(ds); - } - - private Connection getConnection(int major, int minor) throws Exception { - DatabaseMetaData databaseMetaData = Mockito.mock(DatabaseMetaData.class); - Mockito.when(databaseMetaData.getJDBCMajorVersion()).thenReturn(major); - Mockito.when(databaseMetaData.getJDBCMinorVersion()).thenReturn(minor); - Connection connection = Mockito.mock(Connection.class); - Mockito.when(connection.getMetaData()).thenReturn(databaseMetaData); - return connection; - } - - @Test - public void BeginEndRequestJDBC42Test() throws Exception { - Connection connection = getConnection(4,2); - PoolEntry poolEntry = new PoolEntry(connection, poolBase, false, false); - Connection proxyConnection = poolEntry.createProxyConnection(ProxyLeakTask.NO_LEAK); - Mockito.verify(connection, Mockito.never()).beginRequest(); - Mockito.verify(connection, Mockito.never()).endRequest(); - poolEntry.recycle(); - Mockito.verify(connection, Mockito.never()).beginRequest(); - Mockito.verify(connection, Mockito.never()).endRequest(); - Mockito.verify(connection, Mockito.atMostOnce()).getMetaData(); - } - - @Test - public void BeginEndRequestJDBC38Test() throws Exception { - Connection connection = getConnection(3,8); - PoolEntry poolEntry = new PoolEntry(connection, poolBase, false, false); - Connection proxyConnection = poolEntry.createProxyConnection(ProxyLeakTask.NO_LEAK); - Mockito.verify(connection, Mockito.never()).beginRequest(); - Mockito.verify(connection, Mockito.never()).endRequest(); - poolEntry.recycle(); - Mockito.verify(connection, Mockito.never()).beginRequest(); - Mockito.verify(connection, Mockito.never()).endRequest(); - Mockito.verify(connection, Mockito.atMostOnce()).getMetaData(); - } - - @Test - public void BeginEndRequestJDBC43Test() throws Exception { - Connection connection = getConnection(4,3); - PoolEntry poolEntry = new PoolEntry(connection, poolBase, false, false); - Connection proxyConnection = poolEntry.createProxyConnection(ProxyLeakTask.NO_LEAK); - Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); - Mockito.verify(connection, Mockito.never()).endRequest(); - poolEntry.recycle(); - Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); - Mockito.verify(connection, Mockito.atMostOnce()).endRequest(); - Mockito.verify(connection, Mockito.atMostOnce()).getMetaData(); - } - - @Test - public void BeginEndRequestJDBC47Test() throws Exception { - Connection connection = getConnection(4,7); - PoolEntry poolEntry = new PoolEntry(connection, poolBase, false, false); - Connection proxyConnection = poolEntry.createProxyConnection(ProxyLeakTask.NO_LEAK); - Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); - Mockito.verify(connection, Mockito.never()).endRequest(); - poolEntry.recycle(); - Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); - Mockito.verify(connection, Mockito.atMostOnce()).endRequest(); - Mockito.verify(connection, Mockito.atMostOnce()).getMetaData(); - } - - @Test - public void BeginEndRequestJDBC50Test() throws Exception { - Connection connection = getConnection(5,0); - PoolEntry poolEntry = new PoolEntry(connection, poolBase, false, false); - Connection proxyConnection = poolEntry.createProxyConnection(ProxyLeakTask.NO_LEAK); - Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); - Mockito.verify(connection, Mockito.never()).endRequest(); - poolEntry.recycle(); - Mockito.verify(connection, Mockito.atMostOnce()).beginRequest(); - Mockito.verify(connection, Mockito.atMostOnce()).endRequest(); - Mockito.verify(connection, Mockito.atMostOnce()).getMetaData(); - } - -} diff --git a/src/test/java/com/zaxxer/hikari/pool/RequestBoundaryTest.java b/src/test/java/com/zaxxer/hikari/pool/RequestBoundaryTest.java new file mode 100644 index 000000000..add379bb4 --- /dev/null +++ b/src/test/java/com/zaxxer/hikari/pool/RequestBoundaryTest.java @@ -0,0 +1,57 @@ +package com.zaxxer.hikari.pool; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import com.zaxxer.hikari.mocks.StubConnection; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; + +import static com.zaxxer.hikari.pool.TestElf.getPool; +import static com.zaxxer.hikari.pool.TestElf.newHikariConfig; + +public class RequestBoundaryTest { + + private static final HikariConfig config; + static { + config = newHikariConfig(); + config.setMinimumIdle(0); + config.setMaximumPoolSize(10); + config.setInitializationFailTimeout(Long.MAX_VALUE); + config.setConnectionTestQuery("VALUES 1"); + config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); + } + + private HikariPool getHikariPool(boolean enableRequestBoundary) { + System.setProperty("com.zaxxer.hikari.enableRequestBoundary", String.valueOf(enableRequestBoundary)); + HikariDataSource ds = new HikariDataSource(config); + HikariPool pool = getPool(ds); + return pool; + } + + @Test + public void RequestBoundaryEnabledTest() throws Exception { + HikariPool pool = getHikariPool(true); + Connection conn = pool.getConnection(); + Assert.assertTrue("Begin request called", ((StubConnection)conn).beginRequestCalled); + Assert.assertFalse("End request called", ((StubConnection)conn).beginRequestCalled); + conn.close(); + Assert.assertTrue("Begin request called", ((StubConnection)conn).beginRequestCalled); + Assert.assertTrue("End request called", ((StubConnection)conn).beginRequestCalled); + } + + @Test + public void RequestBoundaryDisabledTest() throws Exception { + HikariPool pool = getHikariPool(false); + Connection conn = pool.getConnection(); + Assert.assertFalse("Begin request called", ((StubConnection)conn).beginRequestCalled); + Assert.assertFalse("End request called", ((StubConnection)conn).beginRequestCalled); + conn.close(); + Assert.assertFalse("Begin request called", ((StubConnection)conn).beginRequestCalled); + Assert.assertFalse("End request called", ((StubConnection)conn).beginRequestCalled); + } + +} From 5761a5fa68edb5d8bd62804739e9821d9992d81b Mon Sep 17 00:00:00 2001 From: Fernanda Meheust Date: Mon, 30 Oct 2023 21:04:32 +0100 Subject: [PATCH 14/19] Corrected test --- .../hikari/pool/RequestBoundaryTest.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/test/java/com/zaxxer/hikari/pool/RequestBoundaryTest.java b/src/test/java/com/zaxxer/hikari/pool/RequestBoundaryTest.java index add379bb4..5adfe9c62 100644 --- a/src/test/java/com/zaxxer/hikari/pool/RequestBoundaryTest.java +++ b/src/test/java/com/zaxxer/hikari/pool/RequestBoundaryTest.java @@ -33,25 +33,27 @@ private HikariPool getHikariPool(boolean enableRequestBoundary) { } @Test - public void RequestBoundaryEnabledTest() throws Exception { + public void requestBoundaryEnabledTest() throws Exception { HikariPool pool = getHikariPool(true); Connection conn = pool.getConnection(); - Assert.assertTrue("Begin request called", ((StubConnection)conn).beginRequestCalled); - Assert.assertFalse("End request called", ((StubConnection)conn).beginRequestCalled); + StubConnection stubConnection = conn.unwrap(StubConnection.class); + Assert.assertTrue("Begin request called", stubConnection.beginRequestCalled); + Assert.assertFalse("End request called", stubConnection.endRequestCalled); conn.close(); - Assert.assertTrue("Begin request called", ((StubConnection)conn).beginRequestCalled); - Assert.assertTrue("End request called", ((StubConnection)conn).beginRequestCalled); + Assert.assertTrue("Begin request called", stubConnection.beginRequestCalled); + Assert.assertTrue("End request called", stubConnection.endRequestCalled); } @Test - public void RequestBoundaryDisabledTest() throws Exception { + public void requestBoundaryDisabledTest() throws Exception { HikariPool pool = getHikariPool(false); Connection conn = pool.getConnection(); - Assert.assertFalse("Begin request called", ((StubConnection)conn).beginRequestCalled); - Assert.assertFalse("End request called", ((StubConnection)conn).beginRequestCalled); + StubConnection stubConnection = conn.unwrap(StubConnection.class); + Assert.assertFalse("Begin request called", stubConnection.beginRequestCalled); + Assert.assertFalse("End request called", stubConnection.endRequestCalled); conn.close(); - Assert.assertFalse("Begin request called", ((StubConnection)conn).beginRequestCalled); - Assert.assertFalse("End request called", ((StubConnection)conn).beginRequestCalled); + Assert.assertFalse("Begin request called", stubConnection.beginRequestCalled); + Assert.assertFalse("End request called", stubConnection.endRequestCalled); } } From 5b845f284d76cef77ce0ab8937bdbb458d0fa2bd Mon Sep 17 00:00:00 2001 From: Fernanda Meheust Date: Mon, 30 Oct 2023 21:09:37 +0100 Subject: [PATCH 15/19] Renamed property and tests --- src/main/java/com/zaxxer/hikari/pool/HikariPool.java | 2 +- ...equestBoundaryTest.java => RequestBoundariesTest.java} | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) rename src/test/java/com/zaxxer/hikari/pool/{RequestBoundaryTest.java => RequestBoundariesTest.java} (93%) diff --git a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java index 64e16b63b..b77ad3484 100644 --- a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java +++ b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java @@ -64,7 +64,7 @@ public final class HikariPool extends PoolBase implements HikariPoolMXBean, IBag private final long aliveBypassWindowMs = Long.getLong("com.zaxxer.hikari.aliveBypassWindowMs", MILLISECONDS.toMillis(500)); private final long housekeepingPeriodMs = Long.getLong("com.zaxxer.hikari.housekeeping.periodMs", SECONDS.toMillis(30)); - private final boolean isRequestBoundariesEnabled = Boolean.getBoolean("com.zaxxer.hikari.enableRequestBoundary"); + private final boolean isRequestBoundariesEnabled = Boolean.getBoolean("com.zaxxer.hikari.enableRequestBoundaries"); private static final String EVICTED_CONNECTION_MESSAGE = "(connection was evicted)"; private static final String DEAD_CONNECTION_MESSAGE = "(connection is dead)"; diff --git a/src/test/java/com/zaxxer/hikari/pool/RequestBoundaryTest.java b/src/test/java/com/zaxxer/hikari/pool/RequestBoundariesTest.java similarity index 93% rename from src/test/java/com/zaxxer/hikari/pool/RequestBoundaryTest.java rename to src/test/java/com/zaxxer/hikari/pool/RequestBoundariesTest.java index 5adfe9c62..620a268d3 100644 --- a/src/test/java/com/zaxxer/hikari/pool/RequestBoundaryTest.java +++ b/src/test/java/com/zaxxer/hikari/pool/RequestBoundariesTest.java @@ -5,15 +5,13 @@ import com.zaxxer.hikari.mocks.StubConnection; import org.junit.Assert; import org.junit.Test; -import org.mockito.Mockito; import java.sql.Connection; -import java.sql.DatabaseMetaData; import static com.zaxxer.hikari.pool.TestElf.getPool; import static com.zaxxer.hikari.pool.TestElf.newHikariConfig; -public class RequestBoundaryTest { +public class RequestBoundariesTest { private static final HikariConfig config; static { @@ -25,8 +23,8 @@ public class RequestBoundaryTest { config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); } - private HikariPool getHikariPool(boolean enableRequestBoundary) { - System.setProperty("com.zaxxer.hikari.enableRequestBoundary", String.valueOf(enableRequestBoundary)); + private HikariPool getHikariPool(boolean enableRequestBoundaries) { + System.setProperty("com.zaxxer.hikari.enableRequestBoundaries", String.valueOf(enableRequestBoundaries)); HikariDataSource ds = new HikariDataSource(config); HikariPool pool = getPool(ds); return pool; From a72b575a96ee2ddb36321715d3fa128aa1484f89 Mon Sep 17 00:00:00 2001 From: Fernanda Meheust Date: Mon, 30 Oct 2023 21:28:19 +0100 Subject: [PATCH 16/19] Removed changed to PoolEntry --- src/main/java/com/zaxxer/hikari/pool/PoolEntry.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java index 38c1fed0f..e72b01b4c 100644 --- a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java +++ b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java @@ -21,7 +21,6 @@ import org.slf4j.LoggerFactory; import java.sql.Connection; -import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.concurrent.ScheduledFuture; @@ -56,7 +55,6 @@ final class PoolEntry implements IConcurrentBagEntry private final boolean isReadOnly; private final boolean isAutoCommit; - private boolean isJDBC43OrLater; static { @@ -71,17 +69,6 @@ final class PoolEntry implements IConcurrentBagEntry this.isAutoCommit = isAutoCommit; this.lastAccessed = currentTime(); this.openStatements = new FastList<>(Statement.class, 16); - boolean isJDBC43OrLater = false; - try { - DatabaseMetaData dm = connection.getMetaData(); - isJDBC43OrLater = ((dm != null) && ( - (dm.getJDBCMajorVersion() > 4) || - (dm.getJDBCMajorVersion() == 4 && dm.getJDBCMinorVersion() >= 3) - )); - } catch (SQLException sqlEx) { - LOGGER.warn("getMetaData Failed for: {},({})", connection, sqlEx.getMessage()); - } - this.isJDBC43OrLater = isJDBC43OrLater; } /** From a70ccb0dea09b5e1728f36c5471b2ec987545981 Mon Sep 17 00:00:00 2001 From: Fernanda Meheust Date: Mon, 30 Oct 2023 21:29:24 +0100 Subject: [PATCH 17/19] Removed changes to PoolEntry --- .../com/zaxxer/hikari/pool/PoolEntry.java | 93 ++++++++----------- 1 file changed, 38 insertions(+), 55 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java index e72b01b4c..d0ccdbd3a 100644 --- a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java +++ b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java @@ -34,8 +34,7 @@ * * @author Brett Wooldridge */ -final class PoolEntry implements IConcurrentBagEntry -{ +final class PoolEntry implements IConcurrentBagEntry { private static final Logger LOGGER = LoggerFactory.getLogger(PoolEntry.class); private static final AtomicIntegerFieldUpdater stateUpdater; @@ -56,13 +55,11 @@ final class PoolEntry implements IConcurrentBagEntry private final boolean isReadOnly; private final boolean isAutoCommit; - static - { + static { stateUpdater = AtomicIntegerFieldUpdater.newUpdater(PoolEntry.class, "state"); } - PoolEntry(final Connection connection, final PoolBase pool, final boolean isReadOnly, final boolean isAutoCommit) - { + PoolEntry(final Connection connection, final PoolBase pool, final boolean isReadOnly, final boolean isAutoCommit) { this.connection = connection; this.hikariPool = (HikariPool) pool; this.isReadOnly = isReadOnly; @@ -74,11 +71,9 @@ final class PoolEntry implements IConcurrentBagEntry /** * Release this entry back to the pool. */ - void recycle() - { + void recycle() { if (connection != null) { this.lastAccessed = currentTime(); - hikariPool.recycle(this); } } @@ -86,10 +81,10 @@ void recycle() /** * Set the end of life {@link ScheduledFuture}. * - * @param endOfLife this PoolEntry/Connection's end of life {@link ScheduledFuture} + * @param endOfLife this PoolEntry/Connection's end of life + * {@link ScheduledFuture} */ - void setFutureEol(final ScheduledFuture endOfLife) - { + void setFutureEol(final ScheduledFuture endOfLife) { this.endOfLife = endOfLife; } @@ -97,92 +92,81 @@ public void setKeepalive(ScheduledFuture keepalive) { this.keepalive = keepalive; } - Connection createProxyConnection(final ProxyLeakTask leakTask) - { + Connection createProxyConnection(final ProxyLeakTask leakTask) { return ProxyFactory.getProxyConnection(this, connection, openStatements, leakTask, isReadOnly, isAutoCommit); } - void resetConnectionState(final ProxyConnection proxyConnection, final int dirtyBits) throws SQLException - { + void resetConnectionState(final ProxyConnection proxyConnection, final int dirtyBits) throws SQLException { hikariPool.resetConnectionState(connection, proxyConnection, dirtyBits); } - String getPoolName() - { + String getPoolName() { return hikariPool.toString(); } - boolean isMarkedEvicted() - { + boolean isMarkedEvicted() { return evict; } - void markEvicted() - { + void markEvicted() { this.evict = true; } - void evict(final String closureReason) - { + void evict(final String closureReason) { hikariPool.closeConnection(this, closureReason); } /** Returns millis since lastBorrowed */ - long getMillisSinceBorrowed() - { + long getMillisSinceBorrowed() { return elapsedMillis(lastBorrowed); } - PoolBase getPoolBase() - { + PoolBase getPoolBase() { return hikariPool; } /** {@inheritDoc} */ @Override - public String toString() - { + public String toString() { final var now = currentTime(); return connection - + ", accessed " + elapsedDisplayString(lastAccessed, now) + " ago, " - + stateToString(); + + ", accessed " + elapsedDisplayString(lastAccessed, now) + " ago, " + + stateToString(); } // *********************************************************************** - // IConcurrentBagEntry methods + // IConcurrentBagEntry methods // *********************************************************************** /** {@inheritDoc} */ @Override - public int getState() - { + public int getState() { return stateUpdater.get(this); } /** {@inheritDoc} */ @Override - public boolean compareAndSet(int expect, int update) - { + public boolean compareAndSet(int expect, int update) { return stateUpdater.compareAndSet(this, expect, update); } /** {@inheritDoc} */ @Override - public void setState(int update) - { + public void setState(int update) { stateUpdater.set(this, update); } - Connection close() - { + Connection close() { var eol = endOfLife; if (eol != null && !eol.isDone() && !eol.cancel(false)) { - LOGGER.warn("{} - maxLifeTime expiration task cancellation unexpectedly returned false for connection {}", getPoolName(), connection); + LOGGER.warn("{} - maxLifeTime expiration task cancellation unexpectedly returned false for connection {}", + getPoolName(), connection); } var ka = keepalive; if (ka != null && !ka.isDone() && !ka.cancel(false)) { - LOGGER.warn("{} - keepalive task cancellation unexpectedly returned false for connection {}", getPoolName(), connection); + LOGGER.warn("{} - keepalive task cancellation unexpectedly returned false for connection {}", getPoolName(), + connection); } var con = connection; @@ -192,19 +176,18 @@ Connection close() return con; } - private String stateToString() - { + private String stateToString() { switch (state) { - case STATE_IN_USE: - return "IN_USE"; - case STATE_NOT_IN_USE: - return "NOT_IN_USE"; - case STATE_REMOVED: - return "REMOVED"; - case STATE_RESERVED: - return "RESERVED"; - default: - return "Invalid"; + case STATE_IN_USE: + return "IN_USE"; + case STATE_NOT_IN_USE: + return "NOT_IN_USE"; + case STATE_REMOVED: + return "REMOVED"; + case STATE_RESERVED: + return "RESERVED"; + default: + return "Invalid"; } } } From 56ae7575153a2879dc9271c2e59edcf6f5bde1f3 Mon Sep 17 00:00:00 2001 From: Fernanda Meheust Date: Mon, 30 Oct 2023 21:31:43 +0100 Subject: [PATCH 18/19] Removed changes to PoolEntry --- .../com/zaxxer/hikari/pool/PoolEntry.java | 72 +++++++++++-------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java index d0ccdbd3a..a5093222c 100644 --- a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java +++ b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java @@ -34,7 +34,8 @@ * * @author Brett Wooldridge */ -final class PoolEntry implements IConcurrentBagEntry { +final class PoolEntry implements IConcurrentBagEntry +{ private static final Logger LOGGER = LoggerFactory.getLogger(PoolEntry.class); private static final AtomicIntegerFieldUpdater stateUpdater; @@ -55,11 +56,13 @@ final class PoolEntry implements IConcurrentBagEntry { private final boolean isReadOnly; private final boolean isAutoCommit; - static { + static + { stateUpdater = AtomicIntegerFieldUpdater.newUpdater(PoolEntry.class, "state"); } - PoolEntry(final Connection connection, final PoolBase pool, final boolean isReadOnly, final boolean isAutoCommit) { + PoolEntry(final Connection connection, final PoolBase pool, final boolean isReadOnly, final boolean isAutoCommit) + { this.connection = connection; this.hikariPool = (HikariPool) pool; this.isReadOnly = isReadOnly; @@ -71,7 +74,8 @@ final class PoolEntry implements IConcurrentBagEntry { /** * Release this entry back to the pool. */ - void recycle() { + void recycle() + { if (connection != null) { this.lastAccessed = currentTime(); hikariPool.recycle(this); @@ -81,10 +85,10 @@ void recycle() { /** * Set the end of life {@link ScheduledFuture}. * - * @param endOfLife this PoolEntry/Connection's end of life - * {@link ScheduledFuture} + * @param endOfLife this PoolEntry/Connection's end of life {@link ScheduledFuture} */ - void setFutureEol(final ScheduledFuture endOfLife) { + void setFutureEol(final ScheduledFuture endOfLife) + { this.endOfLife = endOfLife; } @@ -92,81 +96,92 @@ public void setKeepalive(ScheduledFuture keepalive) { this.keepalive = keepalive; } - Connection createProxyConnection(final ProxyLeakTask leakTask) { + Connection createProxyConnection(final ProxyLeakTask leakTask) + { return ProxyFactory.getProxyConnection(this, connection, openStatements, leakTask, isReadOnly, isAutoCommit); } - void resetConnectionState(final ProxyConnection proxyConnection, final int dirtyBits) throws SQLException { + void resetConnectionState(final ProxyConnection proxyConnection, final int dirtyBits) throws SQLException + { hikariPool.resetConnectionState(connection, proxyConnection, dirtyBits); } - String getPoolName() { + String getPoolName() + { return hikariPool.toString(); } - boolean isMarkedEvicted() { + boolean isMarkedEvicted() + { return evict; } - void markEvicted() { + void markEvicted() + { this.evict = true; } - void evict(final String closureReason) { + void evict(final String closureReason) + { hikariPool.closeConnection(this, closureReason); } /** Returns millis since lastBorrowed */ - long getMillisSinceBorrowed() { + long getMillisSinceBorrowed() + { return elapsedMillis(lastBorrowed); } - PoolBase getPoolBase() { + PoolBase getPoolBase() + { return hikariPool; } /** {@inheritDoc} */ @Override - public String toString() { + public String toString() + { final var now = currentTime(); return connection - + ", accessed " + elapsedDisplayString(lastAccessed, now) + " ago, " - + stateToString(); + + ", accessed " + elapsedDisplayString(lastAccessed, now) + " ago, " + + stateToString(); } // *********************************************************************** - // IConcurrentBagEntry methods + // IConcurrentBagEntry methods // *********************************************************************** /** {@inheritDoc} */ @Override - public int getState() { + public int getState() + { return stateUpdater.get(this); } /** {@inheritDoc} */ @Override - public boolean compareAndSet(int expect, int update) { + public boolean compareAndSet(int expect, int update) + { return stateUpdater.compareAndSet(this, expect, update); } /** {@inheritDoc} */ @Override - public void setState(int update) { + public void setState(int update) + { stateUpdater.set(this, update); } - Connection close() { + Connection close() + { var eol = endOfLife; if (eol != null && !eol.isDone() && !eol.cancel(false)) { - LOGGER.warn("{} - maxLifeTime expiration task cancellation unexpectedly returned false for connection {}", - getPoolName(), connection); + LOGGER.warn("{} - maxLifeTime expiration task cancellation unexpectedly returned false for connection {}", getPoolName(), connection); } var ka = keepalive; if (ka != null && !ka.isDone() && !ka.cancel(false)) { - LOGGER.warn("{} - keepalive task cancellation unexpectedly returned false for connection {}", getPoolName(), - connection); + LOGGER.warn("{} - keepalive task cancellation unexpectedly returned false for connection {}", getPoolName(), connection); } var con = connection; @@ -176,7 +191,8 @@ Connection close() { return con; } - private String stateToString() { + private String stateToString() + { switch (state) { case STATE_IN_USE: return "IN_USE"; From 71e238af74e741ba4e0dd75142596990f669937c Mon Sep 17 00:00:00 2001 From: Fernanda Meheust Date: Mon, 30 Oct 2023 21:34:12 +0100 Subject: [PATCH 19/19] Removed changes to PoolEntry --- .../com/zaxxer/hikari/pool/PoolEntry.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java index a5093222c..a2392b913 100644 --- a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java +++ b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java @@ -194,16 +194,16 @@ Connection close() private String stateToString() { switch (state) { - case STATE_IN_USE: - return "IN_USE"; - case STATE_NOT_IN_USE: - return "NOT_IN_USE"; - case STATE_REMOVED: - return "REMOVED"; - case STATE_RESERVED: - return "RESERVED"; - default: - return "Invalid"; + case STATE_IN_USE: + return "IN_USE"; + case STATE_NOT_IN_USE: + return "NOT_IN_USE"; + case STATE_REMOVED: + return "REMOVED"; + case STATE_RESERVED: + return "RESERVED"; + default: + return "Invalid"; } } }