How to Configure Apache DBCP Connection Pool in JDBC?

To configure an Apache DBCP connection pool for “plain” JDBC, you typically create a pooled DataSource once at startup, then get connections from it (and always close them to return to the pool).

Below are the two most common approaches.

1) Recommended (DBCP2): BasicDataSource (simplest)

Create and configure the pool

package org.kodejava.jdbc;

import org.apache.commons.dbcp2.BasicDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public final class Dbcp2Example {
    public static DataSource dataSource() {
        BasicDataSource ds = new BasicDataSource();
        ds.setUrl("jdbc:postgresql://localhost:5432/app");
        ds.setUsername("<db_user>");
        ds.setPassword("<db_password>");

        ds.setMaxTotal(20);
        ds.setMaxIdle(10);
        ds.setMinIdle(2);

        ds.setValidationQuery("SELECT 1");
        ds.setTestOnBorrow(true);

        return ds;
    }

    public static void main(String[] args) throws Exception {
        DataSource ds = dataSource();
        try (Connection c = ds.getConnection();
             PreparedStatement ps = c.prepareStatement("SELECT 1");
             ResultSet rs = ps.executeQuery()) {
            while (rs.next()) System.out.println(rs.getInt(1));
        }
    }
}

Key idea: with pooling, conn.close() does not close the physical DB connection; it returns it to the pool.


2) Lower-level (more flexible): PoolingDataSource + Commons Pool

This approach wires DBCP to Commons Pool manually (useful when you want full control over the pool object/config).

package org.kodejava.jdbc;

import org.apache.commons.dbcp2.ConnectionFactory;
import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
import org.apache.commons.dbcp2.PoolableConnection;
import org.apache.commons.dbcp2.PoolableConnectionFactory;
import org.apache.commons.dbcp2.PoolingDataSource;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import javax.sql.DataSource;

public final class ManualDbcpPoolFactory {

    public static DataSource createDataSource() {
        ConnectionFactory cf =
                new DriverManagerConnectionFactory("jdbc:postgresql://localhost:5432/app",
                        "<db_user>", "<db_password>");

        PoolableConnectionFactory pcf = new PoolableConnectionFactory(cf, null);
        pcf.setValidationQuery("SELECT 1");

        GenericObjectPoolConfig<PoolableConnection> config = new GenericObjectPoolConfig<>();
        config.setMaxTotal(20);
        config.setMaxIdle(10);
        config.setMinIdle(2);
        config.setTestOnBorrow(true);

        GenericObjectPool<PoolableConnection> pool = new GenericObjectPool<>(pcf, config);
        pcf.setPool(pool);

        return new PoolingDataSource<>(pool);
    }
}

Practical tuning checklist (what to set and why)

  • Sizing
    • maxTotal: hard cap of concurrent borrowed connections.
    • maxIdle / minIdle: how many connections to keep around to absorb spikes.
  • Validation
    • Use validationQuery (or validationQueryTimeout) and pick one strategy:
      • testOnBorrow=true (safer, slightly more overhead), or
      • testWhileIdle=true + eviction run (common for reducing borrow-time latency).
  • Timeouts
    • maxWaitMillis: how long callers wait for a free connection before failing.
  • Always close
    • Ensure try-with-resources everywhere; leaks will exhaust the pool.

Maven dependencies

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-dbcp2</artifactId>
        <version>2.14.0</version>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.13.1</version>
    </dependency>

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.7.7</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.