Date: Sun, 21 Jun 2009 13:25:25 -0600
From: p...@valadd.com
To: users@tomcat.apache.org
Subject: Re: Pointers on diagnosing session and thread hangs
"For curiosity's sake, why did you roll your own DB pooling, rather than
letting Tomcat manage it?"
That is a good question and one I am not sure I can easily answer since
the base code I am working with was originally written by someone else 6
years ago. I am not sure if DB pooling was implemented back then, but we
have a particular platform where we need to call some system routines
before making the connection and so this driver is just small piece of
code handles that system call and all the DB connecting and pooling. I
am not sure why the pooling was implemented in this code since my
understanding is that the JDBC driver usually handles this.
We then added some additional support for other DB's into this code so
that the web application can stay completely agnostic to the database it
is connecting to. We specify different JDBC connection information in
the configuration file that the DB Manager code references. So I guess
the bottom line is that this code exists to keep the webapp independent
of the database but why pooling was implemented in the driver is
something that we are now looking into since it appears to be the point
of pain.
FWIW the code from the relevant method is:
public DataSource setupDataSource(String userName, String password,
String connectURI, String roleID, boolean doAdd) {
//
// First, we'll need a ObjectPool that serves as the
// actual pool of connections.
//
// We'll use a GenericObjectPool instance, although
// any ObjectPool implementation will suffice.
//
if(_debug)
System.out.println("Setting up datasource with Role:
"+roleID); //Specific to our implementation
ObjectPool connectionPool = new GenericObjectPool(null, maxActive,
whenExhaustedAction, maxWait, maxIdle, minIdle,
testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis,
numTestsPerEvictionRun, minEvictableIdleTimeMillis,
testWhileIdle);
//
// Next, we'll create a ConnectionFactory that the
// pool will use to create Connections.
// We'll use the DriverManagerConnectionFactory,
// using the connect string passed in the command line
// arguments.
//
ConnectionFactory connectionFactory = new
DriverManagerConnectionFactory(
connectURI, userName, password);
//
// Now we'll create the PoolableConnectionFactory, which wraps
// the "real" Connections created by the ConnectionFactory with
// the classes that implement the pooling functionality.
//
PoolableConnectionFactory pool = null;
// Code to handle member overrides specific to IBM i
if(_debug)
System.out.println("Creating connection pool using
PoolableConnectionFactory");
pool = new PoolableConnectionFactory(
connectionFactory, connectionPool, null, null,
false, true) {
/*
* (non-Javadoc)
*
* @see
org.apache.commons.dbcp.PoolableConnectionFactory#makeObject()
*/
public synchronized Object makeObject() throws Exception {
// This line of code is BLOCKED randomly
Connection conn = (Connection) super.makeObject();
// Code to handle member overrides specific to IBM i
if(_isIBMi.equals("Y"))
if(_debug)
System.out.println("Preparing member
connection");
//Calls the override routines on the IBM i system
databaseManager.prepareMemberConnection(conn);
return conn;
}
};
}
else
{
if(_debug)
System.out.println("Creating connection pool using
PoolableConnectionFactory");
pool = new PoolableConnectionFactory(
connectionFactory, connectionPool, null, null, false, true);
}
//
// Finally, we create the PoolingDriver itself,
// passing in the object pool we created.
//
if(_debug)
System.out.println("Creating PoolingDataSource");
PoolingDataSource dataSource = new
PoolingDataSource(connectionPool);
pool.setDefaultAutoCommit(defaultAutoCommit);
pool.setDefaultCatalog(defaultCatalog);
pool.setDefaultReadOnly(defaultReadOnly);
//pool.setDefaultTransactionIsolation(defaultTransactionIsolation);
if (validationQuery != null)
pool.setValidationQuery(validationQuery);
dataSource
.setAccessToUnderlyingConnectionAllowed(accessToUnderlyingConnectionAllowed);
try {
for (int i = 0; i < initialSize; i++) {
if(_debug)
System.out.println("Adding object to pool up to
initial size");
connectionPool.addObject();
}
}
catch (Exception e) {
e.printStackTrace();
}
if (doAdd == true)
{
if(_debug)
System.out.println("Adding object to pool");
_pools.put(roleID, connectionPool);
_dataSources.put(roleID, dataSource);
}
return dataSource;
}
I will need to find out why the code is structured this way,
particularly the makeObject calls. And, again, the thread dump has been
very helpful in sorting this all out.
Pete
Caldarale, Charles R wrote:
From: Pete Helgren [mailto:p...@valadd.com]
Subject: Re: Pointers on diagnosing session and thread hangs
I am looking at the DB Manager code I wrote to see if I am doing
something wrong in implementing the pooling.
For curiosity's sake, why did you roll your own DB pooling, rather than letting
Tomcat manage it?
- Chuck
THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY
MATERIAL and is thus for use only by the intended recipient. If you received
this in error, please contact the sender and delete the e-mail and its
attachments from all computers.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org