From 21d03d579b5c56bf17d763412179bc7a0e16168c Mon Sep 17 00:00:00 2001
From: Maxim Thomas <maxim.thomas@gmail.com>
Date: Thu, 10 Sep 2026 15:16:32 +0000
Subject: [PATCH] [#885] Bound the wait of a JDBC DDL for a lock another session holds (#936)

---
 opendj-server-legacy/src/main/java/org/opends/server/backends/jdbc/CachedConnection.java |   18 +++++++++++++++++-
 1 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/jdbc/CachedConnection.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/jdbc/CachedConnection.java
index fc3881b..b08ce80 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/jdbc/CachedConnection.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/jdbc/CachedConnection.java
@@ -1199,8 +1199,13 @@
      * read bound that could not be lifted serves the borrower waiting for it and is closed
      * afterwards: left in the pool it would fail every statement slower than that bound - an
      * import batch among them - for every borrow the pool hands it to.
+     * <p>
+     * Turned off during a borrow as well as at establish time ({@link #keepOutOfThePool}): a session
+     * setting a borrower could not take off again is the same kind of thing, and the pool cannot
+     * notice one by itself - {@link #isUsable} validates with {@code isValid()}, a liveness check a
+     * connection carrying a stale setting passes.
      */
-    private final boolean poolable;
+    private volatile boolean poolable;
 
     /**
      * When this connection last answered the database, as a {@link System#nanoTime()} reading:
@@ -1244,6 +1249,17 @@
         this.lastKnownAliveNanos = System.nanoTime();
     }
 
+    /**
+     * Keeps this connection out of the pool: it serves the borrower holding it and is closed rather
+     * than pooled when that borrow ends. For a borrower that left something of its own on the session
+     * and could not take it off again - {@code JDBCStorage.restoreDdlLockBound()} is the one that
+     * does (#885) - where the blast radius is then this one connection instead of every borrow it
+     * would have served after this one.
+     */
+    void keepOutOfThePool() {
+        poolable = false;
+    }
+
     /** Gives back the right to hold this connection, once and only if it was taken. */
     void releasePermit() {
         if (metered && permitReleased.compareAndSet(false, true)) {

--
Gitblit v1.10.0