Tuesday, February 24, 2009

Database Connection Pooling with DBCP

Let's continue with pooling. In this post, I will explain DBCP connection pooling. Here is the sample code for connection pooling without using JOCL.


try {
// connection uri
String uri = "jdbc:mysql://localhost/world";
// load the basic driver
Class.forName("com.mysql.jdbc.Driver");
// create the connection pool
ObjectPool pool = new GenericObjectPool();
// create a connection factory
ConnectionFactory connFactory = new DriverManagerConnectionFactory(
uri, "root", "pwd1234");
// create a poolable connection factory that wraps the
// connectionfactory
PoolableConnectionFactory poolableConnFactory = new PoolableConnectionFactory(
connFactory, pool, null, null, false, true);
// create the pooling driver
Class.forName("org.apache.commons.dbcp.PoolingDriver");
PoolingDriver poolingDriver = (PoolingDriver) DriverManager
.getDriver("jdbc:apache:commons:dbcp:");
poolingDriver.registerPool("demo", pool);
// get connection

Connection conn = null;
for (int i = 0; i < 5; i++) {

System.out.println("Creating connection: " + i);
conn = (Connection) DriverManager
.getConnection("jdbc:apache:commons:dbcp:demo");
Statement stmt = conn.createStatement();

ResultSet rset = stmt.executeQuery("show tables ");
if (i == 2 || i == 8) {
rset.close();
}

}



Before I explain any further let's also have the UML Class diagram






// create a connection factory
ConnectionFactory connFactory = new DriverManagerConnectionFactory(
uri, "root", "pwd1234");


We start with creating a GenericObjectPool and then a ConnectionFactory class. This class is actually responsible for creating a connection to the database and has 1 method of interest CreateConnection(). It creates a connection object for the specified database uri and passes it on.

Next we create a ConnectionFactory for maintaining the lifecycle of the Pool. We use the PoolingDriver object for sql Driver. The Apache Commons Pooling implements its own Driver class called the PoolingDriver which is an implementation of pooling logic for database connections.

PoolingDriver class implements the Driver class and hence overrides the Driver class methods. PoolingDriver class implements pooling logic inside the Connect method. In the onnect method it calls the getConnectionPool method. The method signature looks like this


public synchronized ObjectPool getConnectionPool(String name) throws SQLException


In the pooling test program we had the following code segment


PoolingDriver poolingDriver = (PoolingDriver) DriverManager
.getDriver("jdbc:apache:commons:dbcp:");
poolingDriver.registerPool("example", pool);


The register pool method here adds the Pool object, in this case a GenericPoolObject instance along with the keyword example inside a hash map. So when a call is made inside the getConnectionPool method it has 2 ways of getting a connection

1.Checking the hashmap, if one exists
OR
2.Parsing the jocl file

In this scenario since we are not using a jocl file it gets the “demo” pool object from the hash data structure that we had registered above using PoolingDriver.registerPool. Once it gets the ObjectPool interface it calls the borrowObject method inside it.

From here onwards the implementation is a bit tricky to understand. In our case the ObjectPool is actually an instance of org.apache.commons.pool.impl.GenericObjectPool.
The borrowObject method actually depends on the Factory class methods for actual creation and any other life cycle methods of the Pool. Inside the borrowObject method it calls the

_factory.makeObject()

This call actually ends up in the call for PoolableConnectionFactory.makeObject. It would be interesting to see how this is all interlinked. Its simple when we created the object for PoolableConnectionFactory we passed on the GenericObjectPool to this class and the constructor does the following

_pool.setFactory(this);



So we sucessfully end up setting the factory field to this i.e. PoolableConnectionFactory. Interesting ? Then makeObject method calls the connectionFactory object's createConnection to create an actual Connection method.

Until next post :)

Disclaimer :This post is provided 'as is' and confers no express or implied warranties or rights.