How testOnBorrow Guarantees Reliable DB Connections in Apache Commons DBCP
This article examines the testOnBorrow mechanism in Apache Commons DBCP, detailing how validation occurs at each layer—from the commons‑pool framework through the DBCP implementation down to the MySQL driver—to ensure robust and high‑availability database connections.
1. Framework Layer: commons-pool
The testOnBorrow flag, defined by commons‑pool, determines whether an object is validated before being borrowed from the pool. If validation fails, the object is discarded and another is attempted.
<code>/**
* Borrow an object from the pool. get object from 资源池
* @see org.apache.commons.pool2.impl.GenericObjectPool#borrowObject(long)
*/
public T borrowObject(final long borrowMaxWaitMillis) throws Exception {
PooledObject<T> p = null;
while (p == null) {
p = idleObjects.pollFirst();
if (p != null) {
if (p != null && (getTestOnBorrow() || create && getTestOnCreate())) {
boolean validate = false;
Throwable validationThrowable = null;
try {
// validation implementation provided by the factory
// see org.apache.commons.dbcp2.PoolableConnectionFactory
validate = factory.validateObject(p);
} catch (final Throwable t) {
PoolUtils.checkRethrow(t);
validationThrowable = t;
}
if (!validate) {
try {
// destroy the invalid resource
destroy(p);
destroyedByBorrowValidationCount.incrementAndGet();
} catch (final Exception e) {
// ignore – validation failure is more important
}
p = null;
}
}
}
}
return p.getObject();
}
</code>2. Application Layer: commons-dbcp
Commons‑dbcp builds on commons‑pool to manage database connections. It defines
PoolableConnectionFactoryas a
PooledObjectFactoryand
PoolableConnectionas a
PooledObject.
<code>/**
* @see PoolableConnectionFactory#validateObject(PooledObject)
*/
@Override
public boolean validateObject(final PooledObject<PoolableConnection> p) {
try {
// check creation time against maxConnLifetimeMillis
validateLifetime(p);
// delegate to the actual connection for self‑validation
validateConnection(p.getObject());
return true;
} catch (final Exception e) {
return false;
}
}
/**
* Validate the underlying JDBC connection (closed state, server reachability).
* @see Connection#isValid(int)
*/
public void validateConnection(final PoolableConnection conn) throws SQLException {
if (conn.isClosed()) {
throw new SQLException("validateConnection: connection closed");
}
conn.validate(_validationQuery, _validationQueryTimeout);
}
</code>3. Underlying Layer: mysql‑connector‑java
The MySQL driver implements the standard
java.sql.Connection.isValid(int)method, sending a ping request to verify that the connection is still usable.
<code>/**
* Send a ping request via com.mysql.jdbc.MysqlIO to check availability.
*/
public synchronized boolean isValid(int timeout) throws SQLException {
if (this.isClosed()) {
return false;
} else {
try {
this.pingInternal(false, timeout * 1000);
return true;
} catch (Throwable var5) {
return false;
}
}
}
</code>4. Summary
commons‑pool defines a complete lifecycle interface (makeObject, activateObject, validateObject, passivateObject, destroyObject) that enables precise resource control.
Validation spans multiple time‑related configurations: object creation time, max connection lifetime, JDBC timeout, MySQL idle timeout, each layer contributing to overall reliability.
Connection validation includes checks for closed state at various levels (PoolableConnection, Connection, Socket), providing layered safeguards.
Strict specifications and standards (commons‑pool, JDBC) allow interchangeable implementations and robust integration across components.
5. Understanding High Availability
Examining the MySQL driver source reveals that setting
autoReconnect=truetriggers a high‑availability path where the driver attempts reconnection up to a configurable limit.
<code>// autoReconnect
public void createNewIO(boolean isForReconnect) throws SQLException {
synchronized (getConnectionMutex()) {
// jdbc.url autoReconnect recognized as HighAvailability
if (!getHighAvailability()) {
connectOneTryOnly(isForReconnect, mergedProps);
return;
}
// maxReconnects defaults to 3; failure message: "Attempted reconnect 3 times. Giving up."
connectWithRetries(isForReconnect, mergedProps);
}
}
</code>JD Cloud Developers
JD Cloud Developers (Developer of JD Technology) is a JD Technology Group platform offering technical sharing and communication for AI, cloud computing, IoT and related developers. It publishes JD product technical information, industry content, and tech event news. Embrace technology and partner with developers to envision the future.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.