Showing posts with label DBCP. Show all posts
Showing posts with label DBCP. Show all posts

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.

Tuesday, January 13, 2009

Object pooling using Apache Commons

In this post I will give an introduction to Apache Commons Pools http://commons.apache.org/pool/

What is Pooling and why we need to care


Pooling is a mechanism used for either Object pooling in J2EE application servers or for database connection pooling.

Pooling is important since we know that object creation involves heavy processing. So each time when you request a connection towards database that will end up in creating a new object in the heap. This involves a bit of CPU work. And once your are done the object gets cleaned up from memory.
However, consider a web scenario where there might be thousands of requests towards database and creating and cleaning up connection objects can be time consuming.

Pooling enables the objects to be stored in memory(without any state) when the object is no more in use and retrieve it back to active status whenever the application requests for a new object. This saves the processing time needed for instantiation of an object with each single request. You can get more information on pooling in google.

Apache Commons Pool


In this post I will get started with basics of Commons Pool and which will serve as the basic for understanding Apache DBCP Pooling library which is what is the ultimate goal. Please note that by default most jdbc driver implementations do not implement pooling at the driver level, instead they delegate this task to the Application server or depend on the implementation of application server.

You can download the pools library from the following link http://commons.apache.org/pool/downloads.html and add them to your IDE.

Commons Pools have 2 important packages


org.apache.commons.pool.*;
org.apache.commons.pool.impl.*;



The first package introduces the interfaces required for pooling thereby giving a framework. The second package implements them.

The interface ObjectPool defines the common methods that each implementation of a pool should define. The Commons Pool library provides 2 implementations
of the pool (a) GenericObjectPool and (b) GenericKeyedObjectPool


    • GenericObjectPool: provides a wide variety of configuration options, including the ability to cap the number of idle or active instances, to evict instances as they sit idle in the pool, etc.

      GenericKeyedObjectPool: provides the same functionality but allows you to specify a key for each pool and associated the objects to it


  • The Commons Pool implementation separates the life cycle of the object and the way in which they are pooled. This is done by the means of Factory classes.
    Factory class helps to create, destroy, activate, passivate, and validate instances of the class. The PoolableObjectFactory interface defines life cycle methods
    to be used by an ObjectPool. ObjectPool is the interface that defines how the objects are to be pooled.








    Putting the pieces together


    In order to start with pooling you need to implement a PoolableObjectFactory and define the various life cycle methods viz activateObject,destroyObject,
    makeObject,passivateObject,validateObject for your Object.
    The framework provides you with an abstract class called BasePoolableObjectFactory and so that you dont have to implement all of them.

    Next you need to specify an implementation of ObjectPool in this case we will use a GenericObjectPool which derives from ObjectPool.



    We will begin with defining the object that we need to pool.

    public class LaptopComputer {

    private String operatingSystem;
    private String processor;
    private String memory;


    public String getOperatingSystem() {
    return operatingSystem;
    }
    public void setOperatingSystem(String operatingSystem) {
    this.operatingSystem = operatingSystem;
    }
    public String getProcessor() {
    return processor;
    }
    public void setProcessor(String processor) {
    this.processor = processor;
    }
    public String getMemory() {
    return memory;
    }
    public void setMemory(String memory) {
    this.memory = memory;
    }

    }



    Next we define the PoolableObjectFactory implementation for basic life cycle methods


    public class LaptopComputerObjFactory extends BasePoolableObjectFactory {

    static int i =1;

    @Override
    public Object makeObject() throws Exception {
    System.out.println("\t [LaptopComputerObjFactory] created object "+ i++);



    LaptopComputer tempCompObj = new LaptopComputer();
    //initialize the object
    tempCompObj.setMemory("4 gb");
    tempCompObj.setOperatingSystem("win");
    tempCompObj.setProcessor("X86");

    return tempCompObj;

    }

    @Override
    public void passivateObject(Object obj){

    if( obj != null ){
    System.out.println("\t [LaptopComputerObjFactory] passivating object ");
    //going out of state

    LaptopComputer compObj = (LaptopComputer)obj;
    //neutralize object - release state
    compObj.setMemory(null);
    compObj.setOperatingSystem(null);
    compObj.setProcessor(null);
    }
    }

    @Override
    public void destroyObject(Object obj) {

    if(obj != null) {

    System.out.println("\t [LaptopComputerObjFactory] destroying Object");
    LaptopComputer compObj = (LaptopComputer)obj;
    compObj = null;

    }
    }
    }


    Testing it out in main


    public static void main(String[] args) {


    try {
    GenericObjectPool genObjPool = new GenericObjectPool(new ComputerObjFactory());
    printStats(genObjPool,"Created Object Pool");

    LaptopComputer comp1 = (LaptopComputer)genObjPool.borrowObject();
    //borrow 10 objects from pool
    for(int i=0;i<5;i++)
    {
    genObjPool.borrowObject();
    }


    printStats(genObjPool,"Requested 2 objects");

    //return 1 object
    genObjPool.returnObject(comp1);
    printStats(genObjPool, "Returned 1 object");

    //close the pool
    genObjPool.close();
    printStats(genObjPool, "Pool closed");

    }
    catch(Exception ex) {
    ex.printStackTrace();
    }


    printStats method

    static void printStats(GenericObjectPool genObjPool,String strOperation){
    System.out.println("*******************"+strOperation+"*******************");
    System.out.println("# of Active Pools="+genObjPool.getNumActive());
    System.out.println("# of Idle Pools="+genObjPool.getNumIdle());

    }



    The commons pool implementation uses a doubly linked cursorable list to store the objects. I will delve in more detail about this in the next blog post..