Since Tomcat's JNDI implementation examples use the org.apache.com.dbcp.BasicDataSource, I suspect that a bunch of people have encountered the following problem, as I have: BasicDataSource is not set up to allow overriding of the underlying GenericObjectPool's defaults for time between eviction runs and TTL for idle connections. This has been causing me problems in cases where the database server kills what it presumes to be abandoned connections. In my particular application, it is not possible to use validation queries, mostly because of maintainance concerns, so idle object eviction is the only real solution, but it is disabled by default.

The following patches for BasicDataSource and BasicDataSourceFactory provide the necessary methods to make idle object eviction in the underlying pool configurable while maintaining the same defaults as the GenericObjectPool.

Kris Nuttycombe



Index: BasicDataSource.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/BasicDataSource.java,v
retrieving revision 1.11
diff -u -r1.11 BasicDataSource.java
--- BasicDataSource.java 21 Jul 2002 00:38:35 -0000 1.11
+++ BasicDataSource.java 24 Feb 2003 23:59:32 -0000
@@ -119,6 +119,21 @@



/**
+ * The action to take when a new connection is requested from the pool
+ * and the maximum number of active connections has been met.
+ */
+ protected byte whenExhaustedAction = GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
+
+ public byte getWhenExhaustedAction() {
+ return (this.whenExhaustedAction);
+ }
+
+ public void setWhenExhaustedAction(byte whenExhaustedAction) {
+ this.whenExhaustedAction = whenExhaustedAction;
+ }
+
+
+ /**
* The fully qualified Java class name of the JDBC driver to be used.
*/
protected String driverClassName = null;
@@ -180,6 +195,55 @@



/**
+ * The number of milliseconds to sleep between runs of the
+ * underlying pool's idle object evictor thread.
+ * When non-positive, no idle object evictor thread will be run.
+ */
+ protected long timeBetweenEvictionRunsMillis = GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
+
+ public long getTimeBetweenEvictionRunsMillis() {
+ return (this.timeBetweenEvictionRunsMillis);
+ }
+
+ public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
+ this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
+ }
+
+
+
+ /**
+ * The minimum number of milliseconds that a connection is permitted
+ * to sit idle in the underlying pool before it may be removed by the
+ * idle object eviction thread.
+ */
+ protected long minEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+
+ public long getMinEvictableIdleTimeMillis() {
+ return (this.minEvictableIdleTimeMillis);
+ }
+
+ public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
+ this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+ }
+
+
+
+ /**
+ * The number of objects to examine per run of the idle object evictor.
+ */
+ protected int numTestsPerEvictionRun = GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
+
+ public int getNumTestsPerEvictionRun() {
+ return (this.numTestsPerEvictionRun);
+ }
+
+ public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
+ this.numTestsPerEvictionRun = numTestsPerEvictionRun;
+ }
+
+
+
+ /**
* [Read Only] The current number of active connections that have been
* allocated from this data source.
*/
@@ -543,9 +607,13 @@


// Create an object pool to contain our active connections
connectionPool = new AbandonedObjectPool(null,abandonedConfig);
+ connectionPool.setWhenExhaustedAction(whenExhaustedAction);
connectionPool.setMaxActive(maxActive);
connectionPool.setMaxIdle(maxIdle);
connectionPool.setMaxWait(maxWait);
+ connectionPool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+ connectionPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+ connectionPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
if (validationQuery != null) {
connectionPool.setTestOnBorrow(true);
}





Index: BasicDataSourceFactory.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/BasicDataSourceFactory.java,v
retrieving revision 1.3
diff -u -r1.3 BasicDataSourceFactory.java
--- BasicDataSourceFactory.java 21 Jun 2002 21:56:13 -0000 1.3
+++ BasicDataSourceFactory.java 25 Feb 2003 00:00:23 -0000
@@ -68,6 +68,7 @@
import javax.naming.Reference;
import javax.naming.RefAddr;
import javax.naming.spi.ObjectFactory;
+import org.apache.commons.pool.impl.GenericObjectPool;



/**
@@ -192,6 +193,38 @@
if (ra != null) {
dataSource.setLogAbandoned
(Boolean.valueOf(ra.getContent().toString()).booleanValue());
+ }
+
+ ra = ref.get("timeBetweenEvictionRunsMillis");
+ if (ra != null) {
+ dataSource.setTimeBetweenEvictionRunsMillis
+ (Long.parseLong(ra.getContent().toString()));
+ }
+
+ ra = ref.get("minEvictableIdleTimeMillis");
+ if (ra != null) {
+ dataSource.setMinEvictableIdleTimeMillis
+ (Long.parseLong(ra.getContent().toString()));
+ }
+
+ ra = ref.get("numTestsPerEvictionRun");
+ if (ra != null) {
+ dataSource.setNumTestsPerEvictionRun
+ (Integer.parseInt(ra.getContent().toString()));
+ }
+
+ ra = ref.get("whenExhaustedAction");
+ if (ra != null) {
+ String action = ra.getContent().toString();
+ if ("block".equals(action)) {
+ dataSource.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
+ } else if ("fail".equals(action)) {
+ dataSource.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL);
+ } else if ("grow".equals(action)) {
+ dataSource.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_GROW);
+ } else {
+ dataSource.setWhenExhaustedAction(GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION);
+ }
}


// Return the configured data source instance

--
=====================================================
Kris Nuttycombe
Associate Scientist
Geospatial Data Services Group
CIRES, National Geophysical Data Center/NOAA
(303) 497-6337
[EMAIL PROTECTED]
=====================================================






--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to