Author: jacopoc
Date: Fri Jul 25 13:19:59 2014 New Revision: 1613431 URL: http://svn.apache.org/r1613431 Log: OFBIZ-4283: miscellaneous enhancements to give more control in the configuration of the DBCP connection pool. Thanks to Philippe Mouawad for the initial contribution that I have used as a starting point for a different implementation. Modified: ofbiz/trunk/framework/entity/config/entityengine.xml ofbiz/trunk/framework/entity/dtd/entity-config.xsd ofbiz/trunk/framework/entity/src/org/ofbiz/entity/config/model/InlineJdbc.java ofbiz/trunk/framework/entity/src/org/ofbiz/entity/connection/DBCPConnectionFactory.java ofbiz/trunk/framework/entity/src/org/ofbiz/entity/connection/DebugManagedDataSource.java Modified: ofbiz/trunk/framework/entity/config/entityengine.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/config/entityengine.xml?rev=1613431&r1=1613430&r2=1613431&view=diff ============================================================================== --- ofbiz/trunk/framework/entity/config/entityengine.xml (original) +++ ofbiz/trunk/framework/entity/config/entityengine.xml Fri Jul 25 13:19:59 2014 @@ -182,6 +182,9 @@ access. For a detailed description see t isolation-level="ReadCommitted" pool-minsize="2" pool-maxsize="250" + test-on-borrow="true" + pool-jdbc-test-stmt="values 1" + soft-min-evictable-idle-time-millis="600000" time-between-eviction-runs-millis="600000"/> <!-- <jndi-jdbc jndi-server-name="localjndi" jndi-name="java:/DerbyDataSource" isolation-level="ReadCommitted"/> --> </datasource> Modified: ofbiz/trunk/framework/entity/dtd/entity-config.xsd URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/dtd/entity-config.xsd?rev=1613431&r1=1613430&r2=1613431&view=diff ============================================================================== --- ofbiz/trunk/framework/entity/dtd/entity-config.xsd (original) +++ ofbiz/trunk/framework/entity/dtd/entity-config.xsd Fri Jul 25 13:19:59 2014 @@ -457,15 +457,28 @@ under the License. <xs:attribute type="xs:nonNegativeInteger" name="idle-maxsize"> <xs:annotation> <xs:documentation> - Maximum number of idle connections that should remain in the pool. Defaults to 50% of pool-maxsize. + Maximum number of idle connections that should remain in the pool. Defaults to 50% of pool-maxsize and always greater than pool-minsize. </xs:documentation> </xs:annotation> </xs:attribute> - <xs:attribute type="xs:nonNegativeInteger" name="time-between-eviction-runs-millis" default="600000"/> - <xs:attribute type="xs:nonNegativeInteger" name="pool-sleeptime" default="300000"> + <xs:attribute type="xs:nonNegativeInteger" name="time-between-eviction-runs-millis" default="600000"> <xs:annotation> <xs:documentation> - This parameter is currently not implemented + Sets the number of milliseconds between eviction runs for idle connections. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:nonNegativeInteger" name="soft-min-evictable-idle-time-millis" default="600000"> + <xs:annotation> + <xs:documentation> + Sets the minimum amount of time a connection may sit idle in the pool before it is eligible for eviction. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:nonNegativeInteger" name="pool-sleeptime" default="120000"> + <xs:annotation> + <xs:documentation> + Sets the maximum amount of time (in milliseconds) to wait for a connection when the pool is exhausted </xs:documentation> </xs:annotation> </xs:attribute> @@ -493,7 +506,35 @@ under the License. <xs:attribute type="xs:string" name="pool-jdbc-test-stmt"> <xs:annotation> <xs:documentation> - This parameter is currently not implemented + Connection validation query + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:boolean" name="test-on-create" default="false"> + <xs:annotation> + <xs:documentation> + Run validation query when a connection is created in the pool + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:boolean" name="test-on-borrow" default="false"> + <xs:annotation> + <xs:documentation> + Run validation query when a connection is borrowed from pool + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:boolean" name="test-on-return" default="false"> + <xs:annotation> + <xs:documentation> + Run validation query when a connection is returned to pool + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:boolean" name="test-while-idle" default="false"> + <xs:annotation> + <xs:documentation> + Run validation query while connection is in idle in the pool with frequency set in time-between-eviction-runs-millis </xs:documentation> </xs:annotation> </xs:attribute> Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/config/model/InlineJdbc.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/config/model/InlineJdbc.java?rev=1613431&r1=1613430&r2=1613431&view=diff ============================================================================== --- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/config/model/InlineJdbc.java (original) +++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/config/model/InlineJdbc.java Fri Jul 25 13:19:59 2014 @@ -40,11 +40,16 @@ public final class InlineJdbc extends Jd private final int poolMinsize; // type = xs:nonNegativeInteger private final int idleMaxsize; // type = xs:nonNegativeInteger private final int timeBetweenEvictionRunsMillis; // type = xs:nonNegativeInteger + private final int softMinEvictableIdleTimeMillis; // type = xs:nonNegativeInteger private final int poolSleeptime; // type = xs:nonNegativeInteger private final int poolLifetime; // type = xs:nonNegativeInteger private final int poolDeadlockMaxwait; // type = xs:nonNegativeInteger private final int poolDeadlockRetrywait; // type = xs:nonNegativeInteger private final String poolJdbcTestStmt; // type = xs:string + private final boolean testOnCreate; // type = xs:boolean + private final boolean testOnBorrow; // type = xs:boolean + private final boolean testOnReturn; // type = xs:boolean + private final boolean testWhileIdle; // type = xs:boolean private final String poolXaWrapperClass; // type = xs:string InlineJdbc(Element element) throws GenericEntityConfException { @@ -107,6 +112,16 @@ public final class InlineJdbc extends Jd throw new GenericEntityConfException("<inline-jdbc> element time-between-eviction-runs-millis attribute is invalid" + lineNumberText); } } + String softMinEvictableIdleTimeMillis = element.getAttribute("soft-min-evictable-idle-time-millis"); + if (softMinEvictableIdleTimeMillis.isEmpty()) { + this.softMinEvictableIdleTimeMillis = 600000; + } else { + try { + this.softMinEvictableIdleTimeMillis = Integer.parseInt(softMinEvictableIdleTimeMillis); + } catch (Exception e) { + throw new GenericEntityConfException("<inline-jdbc> element soft-min-evictable-idle-time-millis attribute is invalid" + lineNumberText); + } + } String poolSleeptime = element.getAttribute("pool-sleeptime"); if (poolSleeptime.isEmpty()) { this.poolSleeptime = 300000; @@ -148,6 +163,10 @@ public final class InlineJdbc extends Jd } } this.poolJdbcTestStmt = element.getAttribute("pool-jdbc-test-stmt").intern(); + this.testOnCreate = "true".equals(element.getAttribute("test-on-create")); + this.testOnBorrow = "true".equals(element.getAttribute("test-on-borrow")); + this.testOnReturn = "true".equals(element.getAttribute("test-on-return")); + this.testWhileIdle = "true".equals(element.getAttribute("test-while-idle")); this.poolXaWrapperClass = element.getAttribute("pool-xa-wrapper-class").intern(); } @@ -196,6 +215,11 @@ public final class InlineJdbc extends Jd return this.timeBetweenEvictionRunsMillis; } + /** Returns the value of the <code>time-between-eviction-runs-millis</code> attribute. */ + public int getSoftMinEvictableIdleTimeMillis() { + return this.softMinEvictableIdleTimeMillis; + } + /** Returns the value of the <code>pool-sleeptime</code> attribute. */ public int getPoolSleeptime() { return this.poolSleeptime; @@ -221,6 +245,26 @@ public final class InlineJdbc extends Jd return this.poolJdbcTestStmt; } + /** Returns the value of the <code>test-on-create</code> attribute. */ + public boolean getTestOnCreate() { + return this.testOnCreate; + } + + /** Returns the value of the <code>test-on-create</code> attribute. */ + public boolean getTestOnBorrow() { + return this.testOnBorrow; + } + + /** Returns the value of the <code>test-on-create</code> attribute. */ + public boolean getTestOnReturn() { + return this.testOnReturn; + } + + /** Returns the value of the <code>test-on-create</code> attribute. */ + public boolean getTestWhileIdle() { + return this.testWhileIdle; + } + /** Returns the value of the <code>pool-xa-wrapper-class</code> attribute. */ public String getPoolXaWrapperClass() { return this.poolXaWrapperClass; Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/connection/DBCPConnectionFactory.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/connection/DBCPConnectionFactory.java?rev=1613431&r1=1613430&r2=1613431&view=diff ============================================================================== --- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/connection/DBCPConnectionFactory.java (original) +++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/connection/DBCPConnectionFactory.java Fri Jul 25 13:19:59 2014 @@ -77,9 +77,8 @@ public class DBCPConnectionFactory imple // pool settings int maxSize = jdbcElement.getPoolMaxsize(); int minSize = jdbcElement.getPoolMinsize(); - int timeBetweenEvictionRunsMillis = jdbcElement.getTimeBetweenEvictionRunsMillis(); int maxIdle = jdbcElement.getIdleMaxsize(); - // Don't allow a maxIdle of less than pool-minsize + // maxIdle must be greater than pool-minsize maxIdle = maxIdle > minSize ? maxIdle : minSize; // load the driver Driver jdbcDriver; @@ -106,7 +105,7 @@ public class DBCPConnectionFactory imple // create the pool object factory PoolableConnectionFactory factory = new PoolableManagedConnectionFactory(xacf, null); - factory.setValidationQuery("select 1 from entity_key_store where key_name = ''"); + factory.setValidationQuery(jdbcElement.getPoolJdbcTestStmt()); factory.setDefaultReadOnly(false); String transIso = jdbcElement.getIsolationLevel(); if (!transIso.isEmpty()) { @@ -125,15 +124,28 @@ public class DBCPConnectionFactory imple // configure the pool settings GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); - poolConfig.setMaxWaitMillis(120000); poolConfig.setMaxTotal(maxSize); + // settings for idle connections poolConfig.setMaxIdle(maxIdle); poolConfig.setMinIdle(minSize); - poolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + poolConfig.setTimeBetweenEvictionRunsMillis(jdbcElement.getTimeBetweenEvictionRunsMillis()); + poolConfig.setMinEvictableIdleTimeMillis(-1); // disabled in favour of setSoftMinEvictableIdleTimeMillis(...) + poolConfig.setSoftMinEvictableIdleTimeMillis(jdbcElement.getSoftMinEvictableIdleTimeMillis()); + poolConfig.setNumTestsPerEvictionRun(maxSize); // test all the idle connections + // settings for when the pool is exhausted + poolConfig.setBlockWhenExhausted(true); // the thread requesting the connection waits if no connection is available + poolConfig.setMaxWaitMillis(jdbcElement.getPoolSleeptime()); // throw an exception if, after getPoolSleeptime() ms, no connection is available for the requesting thread + // settings for the execution of the validation query + poolConfig.setTestOnCreate(jdbcElement.getTestOnCreate()); + poolConfig.setTestOnBorrow(jdbcElement.getTestOnBorrow()); + poolConfig.setTestOnReturn(jdbcElement.getTestOnReturn()); + poolConfig.setTestWhileIdle(jdbcElement.getTestWhileIdle()); + GenericObjectPool pool = new GenericObjectPool(factory, poolConfig); + factory.setPool(pool); - // mds = new ManagedDataSource(pool, xacf.getTransactionRegistry()); - mds = new DebugManagedDataSource(pool, xacf.getTransactionRegistry()); // Useful to debug the usage of connections in the pool + mds = new ManagedDataSource(pool, xacf.getTransactionRegistry()); + //mds = new DebugManagedDataSource(pool, xacf.getTransactionRegistry()); // Useful to debug the usage of connections in the pool mds.setAccessToUnderlyingConnectionAllowed(true); // cache the pool Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/connection/DebugManagedDataSource.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/connection/DebugManagedDataSource.java?rev=1613431&r1=1613430&r2=1613431&view=diff ============================================================================== --- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/connection/DebugManagedDataSource.java (original) +++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/connection/DebugManagedDataSource.java Fri Jul 25 13:19:59 2014 @@ -44,9 +44,9 @@ public class DebugManagedDataSource exte if (Debug.verboseOn()) { if (super.getPool() instanceof GenericObjectPool) { GenericObjectPool objectPool = (GenericObjectPool)super.getPool(); - Debug.logVerbose("Borrowing a connection from the pool; used/total: " + objectPool.getNumActive() + "/" + objectPool.getNumActive() + objectPool.getNumIdle() + "; min idle/max idle/max total: " + objectPool.getMinIdle() + "/" + objectPool.getMaxIdle() + "/" + objectPool.getMaxTotal(), module); + Debug.logVerbose("Borrowing a connection from the pool; used/idle/total: " + objectPool.getNumActive() + "/" + objectPool.getNumIdle() + "/" + (objectPool.getNumActive() + objectPool.getNumIdle()) + "; min idle/max idle/max total: " + objectPool.getMinIdle() + "/" + objectPool.getMaxIdle() + "/" + objectPool.getMaxTotal(), module); } else { - Debug.logVerbose("Borrowing a connection from the pool; used/total: " + super.getPool().getNumActive() + "/" + (super.getPool().getNumActive() + super.getPool().getNumIdle()), module); + Debug.logVerbose("Borrowing a connection from the pool; used/idle/total: " + super.getPool().getNumActive() + "/" + super.getPool().getNumIdle() + "/" + (super.getPool().getNumActive() + super.getPool().getNumIdle()), module); } } return super.getConnection(); |
Free forum by Nabble | Edit this page |