You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ja...@apache.org on 2014/07/25 15:20:00 UTC

svn commit: r1613431 - in /ofbiz/trunk/framework/entity: config/ dtd/ src/org/ofbiz/entity/config/model/ src/org/ofbiz/entity/connection/

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();