Author: fhanik
Date: Fri Nov 13 21:53:13 2009
New Revision: 836011
URL: http://svn.apache.org/viewvc?rev=836011&view=rev
Log:
Implement suspectTimeout to allow JMX notifications and log events to take
place if a connection is checked out for too long. But don't abandon/close the
connection.
Modified:
tomcat/trunk/modules/jdbc-pool/.classpath
tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
Modified: tomcat/trunk/modules/jdbc-pool/.classpath
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/.classpath?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/.classpath (original)
+++ tomcat/trunk/modules/jdbc-pool/.classpath Fri Nov 13 21:53:13 2009
@@ -6,5 +6,6 @@
<classpathentry kind="con"
path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
<classpathentry kind="var"
path="TOMCAT_LIBS_BASE/tomcat6-deps/dbcp/tomcat-dbcp.jar"
sourcepath="/TOMCAT_LIBS_BASE/tomcat6-deps/dbcp/src/java"/>
<classpathentry kind="con"
path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="lib"
path="/development/tomcat/trunk/trunk/modules/jdbc-pool/includes/h2/bin/h2-1.1.115.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Modified: tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml (original)
+++ tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml Fri Nov 13 21:53:13 2009
@@ -78,13 +78,16 @@
<li>Asynchronous connection retrieval - you can queue your request for a
connection and receive a Future<Connection> back.</li>
<li>Better idle connection handling. Instead of closing connections
directly, it can still pool connections and sizes the idle pool with a smarter
algorithm.</li>
<li>You can decide at what moment connections are considered abandoned,
is it when the pool is full, or directly at a timeout
- by specifying a threshold.
+ by specifying a pool usage threshold.
</li>
<li>The abandon connection timer will reset upon a statement/query
activity. Allowing a connections that is in use for a long time to not timeout.
This is achieved using the ResetAbandonedTimer
</li>
<li>Close connections after they have been connected for a certain time.
Age based close upon return to the pool.
- </li>
+ </li>
+ <li>Get JMX notifications and log entries when connections are suspected
for being abandoned. This is similar to
+ the <code>removeAbandonedTimeout</code> but it doesn't take any
action, only reports the information.
+ This is achieved using the <code>suspectTimeout</code>
attribute.</li>
</ol>
</p>
@@ -388,6 +391,16 @@
The default value is <code>true</code>.
</p>
</attribute>
+ <attribute name="suspectTimeout" required="false">
+ <p>(int) Timeout value in seconds. Default value is <code>0</code>.<br/>
+ Similar to to the <code>removeAbandonedTimeout</code> value but
instead of treating the connection
+ as abandoned, and potentially closing the connection, this simply
logs the warning if
+ <code>logAbandoned</code> is set to true. If this value is equal or
less than 0, no suspect
+ checking will be performed. Suspect checking only takes place if
the timeout value is larger than 0 and
+ the connection was not abandoned or if abandon check is disabled.
If a connection is suspect a WARN message gets
+ logged and a JMX notification gets sent once.
+ </p>
+ </attribute>
</attributes>
</subsection>
</section>
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
Fri Nov 13 21:53:13 2009
@@ -475,6 +475,32 @@
con.unlock();
}
}
+
+ /**
+ * thread safe way to abandon a connection
+ * signals a connection to be abandoned.
+ * this will disconnect the connection, and log the stack trace if
logAbanded=true
+ * @param con PooledConnection
+ */
+ protected void suspect(PooledConnection con) {
+ if (con == null)
+ return;
+ if (con.isSuspect())
+ return;
+ try {
+ con.lock();
+ String trace = con.getStackTrace();
+ if (getPoolProperties().isLogAbandoned()) {
+ log.warn("Connection has been marked suspect, possibly
abandoned " + con + "["+(System.currentTimeMillis()-con.getTimestamp())+"
ms.]:" + trace);
+ }
+ if (jmxPool!=null) {
+
jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.SUSPECT_ABANDONED_NOTIFICATION,
trace);
+ }
+ con.setSuspect(true);
+ } finally {
+ con.unlock();
+ }
+ }
/**
* thread safe way to release a connection
@@ -786,8 +812,8 @@
public void checkAbandoned() {
try {
if (busy.size()==0) return;
- if (!shouldAbandon()) return;
Iterator<PooledConnection> locked = busy.iterator();
+ int sto = getPoolProperties().getSuspectTimeout();
while (locked.hasNext()) {
PooledConnection con = locked.next();
boolean setToNull = false;
@@ -799,10 +825,12 @@
continue;
long time = con.getTimestamp();
long now = System.currentTimeMillis();
- if ((now - time) > con.getAbandonTimeout()) {
+ if (shouldAbandon() && (now - time) >
con.getAbandonTimeout()) {
busy.remove(con);
abandon(con);
setToNull = true;
+ } else if (sto > 0 && (now - time) > (sto*1000)) {
+ suspect(con);
} else {
//do nothing
} //end if
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
Fri Nov 13 21:53:13 2009
@@ -516,6 +516,23 @@
}
+
+ /**
+ * {...@inheritdoc}
+ */
+ @Override
+ public int getSuspectTimeout() {
+ return getPoolProperties().getSuspectTimeout();
+ }
+
+ /**
+ * {...@inheritdoc}
+ */
+ @Override
+ public void setSuspectTimeout(int seconds) {
+ getPoolProperties().setSuspectTimeout(seconds);
+ }
+
//===============================================================================
// Expose JMX attributes through Tomcat's dynamic reflection
//===============================================================================
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
Fri Nov 13 21:53:13 2009
@@ -698,5 +698,24 @@
* @param useLock set to true if a lock should be used on connection
operations
*/
public void setUseLock(boolean useLock);
+
+ /**
+ * Similar to {...@link #setRemoveAbandonedTimeout(int)} but instead of
treating the connection
+ * as abandoned, and potentially closing the connection, this simply logs
the warning if
+ * {...@link #isLogAbandoned()} returns true. If this value is equal or
less than 0, no suspect
+ * checking will be performed. Suspect checking only takes place if the
timeout value is larger than 0 and
+ * the connection was not abandoned or if abandon check is disabled. If a
connection is suspect a WARN message gets
+ * logged and a JMX notification gets sent once.
+ * @param seconds - the amount of time in seconds that has to pass before
a connection is marked suspect.
+ */
+ public void setSuspectTimeout(int seconds);
+
+ /**
+ * Returns the time in seconds to pass before a connection is marked an
abanoned suspect.
+ * Any value lesser than or equal to 0 means the check is disabled.
+ * @return Returns the time in seconds to pass before a connection is
marked an abanoned suspect.
+ */
+ public int getSuspectTimeout();
+
}
\ No newline at end of file
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
Fri Nov 13 21:53:13 2009
@@ -74,6 +74,8 @@
protected long maxAge = 0;
protected boolean useLock = false;
private InterceptorDefinition[] interceptors = null;
+ protected int suspectTimeout = 0;
+
/**
* {...@inheritdoc}
@@ -718,14 +720,32 @@
return defaultReadOnly;
}
+
+ /**
+ * {...@inheritdoc}
+ */
+ @Override
+ public int getSuspectTimeout() {
+ return this.suspectTimeout;
+ }
+
+ /**
+ * {...@inheritdoc}
+ */
+ @Override
+ public void setSuspectTimeout(int seconds) {
+ this.suspectTimeout = seconds;
+ }
+
/**
* {...@inheritdoc}
*/
@Override
public boolean isPoolSweeperEnabled() {
- boolean result = getTimeBetweenEvictionRunsMillis()>0;
- result = result && (isRemoveAbandoned() &&
getRemoveAbandonedTimeout()>0);
- result = result || (isTestWhileIdle() && getValidationQuery()!=null);
+ boolean timer = getTimeBetweenEvictionRunsMillis()>0;
+ boolean result = timer && (isRemoveAbandoned() &&
getRemoveAbandonedTimeout()>0);
+ result = result || (timer && getSuspectTimeout()>0);
+ result = result || (timer && isTestWhileIdle() &&
getValidationQuery()!=null);
return result;
}
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
Fri Nov 13 21:53:13 2009
@@ -111,6 +111,8 @@
private AtomicBoolean released = new AtomicBoolean(false);
+ private volatile boolean suspect = false;
+
/**
* Constructor
* @param prop - pool properties
@@ -390,6 +392,18 @@
*/
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
+ setSuspect(false);
+ }
+
+
+
+
+ public boolean isSuspect() {
+ return suspect;
+ }
+
+ public void setSuspect(boolean suspect) {
+ this.suspect = suspect;
}
/**
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
Fri Nov 13 21:53:13 2009
@@ -73,7 +73,7 @@
* Invoked when a query execution, a call to execute/executeQuery or
executeBatch failed.
* @param query the query that was executed and failed
* @param args the arguments to the execution
- * @param name the name of the method used to execute {...@link
AbstractCreateStatementInterceptor#executes}
+ * @param name the name of the method used to execute {...@link
AbstractCreateStatementInterceptor#isExecute(Method, boolean)}
* @param start the time the query execution started
* @param t the exception that happened
* @return - the SQL that was executed or the string "batch" if
it was a batch execution
@@ -92,7 +92,7 @@
* Invoked when a query execution, a call to execute/executeQuery or
executeBatch succeeded and was within the timing threshold
* @param query the query that was executed and failed
* @param args the arguments to the execution
- * @param name the name of the method used to execute {...@link
AbstractCreateStatementInterceptor#executes}
+ * @param name the name of the method used to execute {...@link
AbstractCreateStatementInterceptor#isExecute(Method, boolean)}
* @param start the time the query execution started
* @param delta the time the execution took
* @return - the SQL that was executed or the string "batch" if
it was a batch execution
@@ -111,7 +111,7 @@
* Invoked when a query execution, a call to execute/executeQuery or
executeBatch succeeded and was exceeded the timing threshold
* @param query the query that was executed and failed
* @param args the arguments to the execution
- * @param name the name of the method used to execute {...@link
AbstractCreateStatementInterceptor#executes}
+ * @param name the name of the method used to execute {...@link
AbstractCreateStatementInterceptor#isExecute(Method, boolean)}
* @param start the time the query execution started
* @param delta the time the execution took
* @return - the SQL that was executed or the string "batch" if
it was a batch execution
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
Fri Nov 13 21:53:13 2009
@@ -72,6 +72,7 @@
public static final String NOTIFY_ABANDON = "CONNECTION ABANDONED";
public static final String SLOW_QUERY_NOTIFICATION = "SLOW QUERY";
public static final String FAILED_QUERY_NOTIFICATION = "FAILED QUERY";
+ public static final String SUSPECT_ABANDONED_NOTIFICATION = "SUSPECT
CONNETION ABANDONED";
@@ -86,7 +87,7 @@
}
public static MBeanNotificationInfo[] getDefaultNotificationInfo() {
- String[] types = new String[] {NOTIFY_INIT, NOTIFY_CONNECT,
NOTIFY_ABANDON, SLOW_QUERY_NOTIFICATION, FAILED_QUERY_NOTIFICATION};
+ String[] types = new String[] {NOTIFY_INIT, NOTIFY_CONNECT,
NOTIFY_ABANDON, SLOW_QUERY_NOTIFICATION, FAILED_QUERY_NOTIFICATION,
SUSPECT_ABANDONED_NOTIFICATION};
String name = Notification.class.getName();
String description = "A connection pool error condition was met.";
MBeanNotificationInfo info = new MBeanNotificationInfo(types, name,
description);
@@ -553,5 +554,21 @@
// TODO Auto-generated method stub
}
+
+ /**
+ * {...@inheritdoc}
+ */
+ @Override
+ public int getSuspectTimeout() {
+ return getPoolProperties().getSuspectTimeout();
+ }
+
+ /**
+ * {...@inheritdoc}
+ */
+ @Override
+ public void setSuspectTimeout(int seconds) {
+ //no op
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]