This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-dbcp.git
commit ea6dba616e1447def1470ea200b5c9790dcfc13d Author: Gary D. Gregory <garydgreg...@gmail.com> AuthorDate: Mon May 26 10:00:36 2025 -0400 Fix SpotBugs [ERROR] Medium: Operation on the "fatalSqlExceptionThrown" shared variable in "PoolableConnection" class is not atomic [org.apache.commons.dbcp2.PoolableConnection] AT_NONATOMIC_OPERATIONS_ON_SHARED_VARIABLE --- src/changes/changes.xml | 1 + src/main/java/org/apache/commons/dbcp2/PoolableConnection.java | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 1ee7f6bd..43546b93 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -79,6 +79,7 @@ The <action> type attribute can be add,update,fix,remove. <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix SpotBugs [ERROR] Medium: Shared primitive variable "closed" in one thread may not yield the value of the most recent write from another thread [org.apache.commons.dbcp2.cpdsadapter.PooledConnectionImpl] AT_STALE_THREAD_WRITE_OF_PRIMITIVE.</action> <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix SpotBugs [ERROR] Medium: Shared primitive variable "closed" in one thread may not yield the value of the most recent write from another thread [org.apache.commons.dbcp2.DelegatingStatement] AT_STALE_THREAD_WRITE_OF_PRIMITIVE.</action> <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix SpotBugs [ERROR] Medium: Shared primitive variable "cacheState" in one thread may not yield the value of the most recent write from another thread [org.apache.commons.dbcp2.DelegatingConnection] AT_STALE_THREAD_WRITE_OF_PRIMITIVE.</action> + <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix SpotBugs [ERROR] Medium: Operation on the "fatalSqlExceptionThrown" shared variable in "PoolableConnection" class is not atomic [org.apache.commons.dbcp2.PoolableConnection] AT_NONATOMIC_OPERATIONS_ON_SHARED_VARIABLE.</action> <!-- ADD --> <!-- UPDATE --> <action type="update" dev="ggregory" due-to="Gary Gregory">Bump org.apache.commons:commons-parent from 78 to 81.</action> diff --git a/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java b/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java index 5c28f930..8653ef98 100644 --- a/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java +++ b/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java @@ -24,6 +24,7 @@ import java.sql.SQLException; import java.time.Duration; import java.util.Collection; import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -68,7 +69,7 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme * Indicate that unrecoverable SQLException was thrown when using this connection. Such a connection should be * considered broken and not pass validation in the future. */ - private boolean fatalSqlExceptionThrown; + private AtomicBoolean fatalSqlExceptionThrown = new AtomicBoolean(); /** * SQL State codes considered to signal fatal conditions. Overrides the defaults in @@ -259,7 +260,7 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme @Override protected void handleException(final SQLException e) throws SQLException { - fatalSqlExceptionThrown |= isFatalException(e); + fatalSqlExceptionThrown.compareAndSet(false, isFatalException(e)); super.handleException(e); } @@ -407,7 +408,7 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme * @since 2.10.0 */ public void validate(final String sql, Duration timeoutDuration) throws SQLException { - if (fastFailValidation && fatalSqlExceptionThrown) { + if (fastFailValidation && fatalSqlExceptionThrown.get()) { throw new SQLException(Utils.getMessage("poolableConnection.validate.fastFail")); }