Skip to content

Make DbConnectionFactory.getConnection() try-with-resources safe #34948

@spbolton

Description

@spbolton

Description

DbConnectionFactory.getConnection() returns a ThreadLocal-managed connection. Using it in try-with-resources causes close() to run on that connection when the block exits, which corrupts ThreadLocal state and can lead to connection leaks or pool exhaustion.

Problem: Callers (e.g. DatabaseHealthCheck, DatabaseHealthEventManager) use:

try (Connection conn = DbConnectionFactory.getConnection()) { ... }

When close() runs, it returns the connection to the pool but leaves a stale reference in the ThreadLocal, or worse, removes the wrong connection from the holder.

Proposed solution: Add a wrapper (e.g. TryWithResourcesSafeConnection) that only actually closes the connection when it was opened by the current call — matching the semantics of @CloseDBIfOpened. When ownsConnection is true, close() removes from ThreadLocal and closes. When false, close() is a no-op.

Acceptance Criteria

  • getConnection() returns a wrapper that is safe for try-with-resources
  • Closing the wrapper only closes the connection when this call opened it (no prior connection existed)
  • Existing callers using closeSilently() / closeAndCommit() continue to work unchanged
  • Identity checks (e.g. DbConnectionFactory.getConnection() != connection) still work (same wrapper instance returned for existing connection)
  • closeConnection() handles the wrapper correctly (no ConcurrentModificationException)

Additional Context

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status

    QA

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions