(boolean) Set to true if you wish the ProxyConnection class to use String.equals instead of
== when comparing method names. This property does not apply to added interceptors as those are configured individually.
@@ -419,6 +428,18 @@
+
+
+ The abandoned timer starts when a connection is checked out from the pool.
+ This means if you have a 30second timeout and run 10x10second queries using the connection
+ it will be marked abandoned and potentially reclaimed depending on the abandonWhenPercentageFull
+ attribute.
+ Using this interceptor it will reset the checkout timer every time you perform an operation on the connection or execute a
+ query successfully.
+
+
+
+
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
index 2cea90d2b..f5a39a255 100644
--- a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
+++ b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
@@ -654,9 +654,19 @@ public class ConnectionPool {
} //end if
} //checkIn
+ public boolean shouldAbandon() {
+ if (poolProperties.getAbandonWhenPercentageFull()==0) return true;
+ float used = (float)busy.size();
+ float max = (float)poolProperties.getMaxActive();
+ float perc = (float)poolProperties.getAbandonWhenPercentageFull();
+ System.out.println("Abandon rate:"+(used/max*100f));
+ return (used/max*100f)>=perc;
+ }
+
public void checkAbandoned() {
try {
if (busy.size()==0) return;
+ if (!shouldAbandon()) return;
Iterator locked = busy.iterator();
while (locked.hasNext()) {
PooledConnection con = locked.next();
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java
index 94b84a68c..65eb82ddd 100644
--- a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java
+++ b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java
@@ -374,6 +374,14 @@ public class DataSource extends DataSourceProxy implements MBeanRegistration,jav
}
}
+ public int getAbandonWhenPercentageFull() {
+ try {
+ return createPool().getPoolProperties().getAbandonWhenPercentageFull();
+ }catch (SQLException x) {
+ throw new RuntimeException(x);
+ }
+ }
+
public boolean isTestOnBorrow() {
try {
return createPool().getPoolProperties().isTestOnBorrow();
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java
index d78388bf3..ac09e202c 100644
--- a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java
+++ b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java
@@ -94,6 +94,7 @@ public class DataSourceFactory implements ObjectFactory {
protected final static String PROP_REMOVEABANDONED = "removeAbandoned";
protected final static String PROP_REMOVEABANDONEDTIMEOUT = "removeAbandonedTimeout";
protected final static String PROP_LOGABANDONED = "logAbandoned";
+ protected final static String PROP_ABANDONWHENPERCENTAGEFULL = "abandonWhenPercentageFull";
protected final static String PROP_POOLPREPAREDSTATEMENTS = "poolPreparedStatements";
protected final static String PROP_MAXOPENPREPAREDSTATEMENTS = "maxOpenPreparedStatements";
@@ -147,7 +148,8 @@ public class DataSourceFactory implements ObjectFactory {
PROP_JMX_ENABLED,
PROP_FAIR_QUEUE,
PROP_USE_EQUALS,
- OBJECT_NAME
+ OBJECT_NAME,
+ PROP_ABANDONWHENPERCENTAGEFULL
};
// -------------------------------------------------- ObjectFactory Methods
@@ -409,9 +411,13 @@ public class DataSourceFactory implements ObjectFactory {
if (value != null) {
poolProperties.setName(ObjectName.quote(value));
}
-
- return poolProperties;
+ value = properties.getProperty(PROP_ABANDONWHENPERCENTAGEFULL);
+ if (value != null) {
+ poolProperties.setAbandonWhenPercentageFull(Integer.parseInt(value));
+ }
+
+ return poolProperties;
}
/**
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
index 760d347cd..37e01d244 100644
--- a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
+++ b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
@@ -67,12 +67,23 @@ public class PoolProperties {
protected boolean jmxEnabled = true;
protected String initSQL;
protected boolean testOnConnect =false;
- private String jdbcInterceptors=null;
- private boolean fairQueue = true;
- private boolean useEquals = false;
+ protected String jdbcInterceptors=null;
+ protected boolean fairQueue = true;
+ protected boolean useEquals = false;
+ protected int abandonWhenPercentageFull = 0;
private InterceptorDefinition[] interceptors = null;
+ public void setAbandonWhenPercentageFull(int percentage) {
+ if (percentage<0) abandonWhenPercentageFull = 0;
+ else if (percentage>100) abandonWhenPercentageFull = 100;
+ else abandonWhenPercentageFull = percentage;
+ }
+
+ public int getAbandonWhenPercentageFull() {
+ return abandonWhenPercentageFull;
+ }
+
public boolean isFairQueue() {
return fairQueue;
}
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
index fe8b26eaf..46b1763cc 100644
--- a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
+++ b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
@@ -51,7 +51,6 @@ public abstract class AbstractQueryReport extends AbstractCreateStatementInterce
super();
}
-
/**
* Invoked when prepareStatement has been called and completed.
* @param sql - the string used to prepare the statement with
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/ResetAbandonedTimer.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/ResetAbandonedTimer.java
new file mode 100644
index 000000000..fd0f56759
--- /dev/null
+++ b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/ResetAbandonedTimer.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.jdbc.pool.interceptor;
+
+import java.lang.reflect.Method;
+
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+import org.apache.tomcat.jdbc.pool.ProxyConnection;
+
+/**
+ * Class that resets the abandoned timer on any activity on the
+ * Connection or any successful query executions
+ * @author fhanik
+ *
+ */
+public class ResetAbandonedTimer extends AbstractQueryReport {
+
+ public ResetAbandonedTimer() {
+ // TODO Auto-generated constructor stub
+ }
+
+ public boolean resetTimer() {
+ boolean result = false;
+ JdbcInterceptor interceptor = this.getNext();
+ while (interceptor!=null && result==false) {
+ if (interceptor instanceof ProxyConnection) {
+ PooledConnection con = ((ProxyConnection)interceptor).getConnection();
+ if (con!=null) {
+ con.setTimestamp(System.currentTimeMillis());
+ result = true;
+ } else {
+ break;
+ }
+ }
+ interceptor = interceptor.getNext();
+ }
+ return result;
+ }
+
+
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ // TODO Auto-generated method stub
+ Object result = super.invoke(proxy, method, args);
+ resetTimer();
+ return result;
+ }
+
+ @Override
+ protected void prepareCall(String query, long time) {
+ resetTimer();
+ }
+
+ @Override
+ protected void prepareStatement(String sql, long time) {
+ resetTimer();
+
+ }
+
+ @Override
+ public void closeInvoked() {
+ resetTimer();
+ }
+
+ @Override
+ protected String reportQuery(String query, Object[] args, String name,long start, long delta) {
+ resetTimer();
+ return super.reportQuery(query, args, name, start, delta);
+ }
+
+ @Override
+ protected String reportSlowQuery(String query, Object[] args, String name,long start, long delta) {
+ resetTimer();
+ return super.reportSlowQuery(query, args, name, start, delta);
+ }
+}
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
index a658d9858..cdc18a1fc 100644
--- a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
+++ b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
@@ -273,5 +273,8 @@ public class ConnectionPool extends NotificationBroadcasterSupport implements Co
public int getWaitCount() {
return pool.getWaitCount();
}
+ public int getAbandonWhenPercentageFull() {
+ return pool.getPoolProperties().getAbandonWhenPercentageFull();
+ }
}
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java
index 904c4beea..1b8711bfa 100644
--- a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java
+++ b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java
@@ -116,4 +116,6 @@ public interface ConnectionPoolMBean {
public String getJdbcInterceptors();
+ public int getAbandonWhenPercentageFull();
+
}