Why Does Druid Throw “Connection Holder Is Null” and How to Fix It?

This article examines recurring “connection holder is null” errors in Druid’s connection pool, explains how the holder is assigned and cleared, analyzes two real‑world cases—long‑running transactions and killed connections—and offers practical configuration recommendations to prevent the issue.

Programmer DD
Programmer DD
Programmer DD
Why Does Druid Throw “Connection Holder Is Null” and How to Fix It?

System has encountered several “connection holder is null” problems; some resolved, some not.

First, Druid connection pool implementation:

DruidPooledConnection is a static proxy holding a ConnectionHolder; the holder contains the actual connection. Every database‑related method checks checkState() and throws “connection holder is null” if the holder is null.

The ConnectionHolder is set when Datasource.getConnection() retrieves a cached holder from the pool’s array. A new DruidPooledConnection wraps this holder, so each call gets a different proxy.

First occurrence: long‑running transaction exceeds 60 seconds

The holder is initially non‑null; the error appears when another thread nullifies it, typically after transaction commit. Druid’s “remove abandoned connection” feature can reclaim connections that haven’t been returned within the configured timeout (60 s in our case), causing the exception.

Recommendation: disable “remove abandoned” in production; optionally enable testOnBorrow. Do not enable testWhileIdle under high concurrency.

Second occurrence: DBA kills a long‑running transaction

The root cause of the long‑uncommitted transaction is still unknown; MySQL’s innodb_trx and lock tables show no clues.

When the connection is killed, the application sees errors such as:

Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure. The last packet successfully received from the server was 20,840 milliseconds ago.
connection holder is null

The first two indicate a broken TCP connection. Druid catches the exception, uses ExceptionSorter to decide if it’s recoverable. For unrecoverable errors, the connection is removed from the pool, but the conversion process itself may trigger “connection holder is null” because metadata retrieval requires a live connection.

Note that the “connection holder is null” exception is reported only once per failure, unlike the frequent occurrences in our project, whose cause remains unidentified.

Additional note: MySQL’s rollback_on_timeout defaults to off; it rolls back only the last statement on timeout. Usually the application should handle lock acquisition failures and invoke connection.rollback() when a transaction is active.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavadatabaseException HandlingConnection PoolDruid
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.