You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2011/11/20 19:24:16 UTC
svn commit: r1204203 - in /tomcat/trunk/modules/jdbc-pool: doc/
src/main/java/org/apache/tomcat/jdbc/pool/
src/main/java/org/apache/tomcat/jdbc/pool/interceptor/
src/main/java/org/apache/tomcat/jdbc/pool/jmx/
src/test/java/org/apache/tomcat/jdbc/test/ ...
Author: fhanik
Date: Sun Nov 20 18:24:16 2011
New Revision: 1204203
URL: http://svn.apache.org/viewvc?rev=1204203&view=rev
Log:
1. Implement a query timeout intercept to allow for timeouts to be set when statemements are created
2. Implement rollbackOnReturn and commitOnReturn attributes for connections that have autocommit=false
Added:
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/QueryTimeoutInterceptor.java
tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestQueryTimeoutInterceptor.java
Modified:
tomcat/trunk/modules/jdbc-pool/doc/changelog.xml
tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java
Modified: tomcat/trunk/modules/jdbc-pool/doc/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/doc/changelog.xml?rev=1204203&r1=1204202&r2=1204203&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/doc/changelog.xml (original)
+++ tomcat/trunk/modules/jdbc-pool/doc/changelog.xml Sun Nov 20 18:24:16 2011
@@ -33,6 +33,7 @@
<changelog>
<fix><rev>1073531</rev> <bug>50805</bug> Only initialize connections once when async (fhanik)</fix>
<fix><rev>1076380</rev> <bug>50857</bug> Correctly handle timeouts when the pool is busy when async (fhanik)</fix>
+ <add>Added QueryTimeoutInterceptor to be able to configure timeouts on running queries automatically.</add>
</changelog>
</subsection>
</section>
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=1204203&r1=1204202&r2=1204203&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml (original)
+++ tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml Sun Nov 20 18:24:16 2011
@@ -416,6 +416,17 @@
logged and a JMX notification gets sent once.
</p>
</attribute>
+ <attribute name="rollbackOnReturn" required="false">
+ <p>(boolean) If <code>autoCommit==false</code> then the pool can terminate the transaction by calling rollback on the connection as it is returned to the pool
+ Default value is <code>false</code>.<br/>
+ </p>
+ </attribute>
+ <attribute name="commitOnReturn" required="false">
+ <p>(boolean) If <code>autoCommit==false</code> then the pool can complete the transaction by calling commit on the connection as it is returned to the pool
+ If <code>rollbackOnReturn==true</code> then this attribute is ignored.
+ Default value is <code>false</code>.<br/>
+ </p>
+ </attribute>
<attribute name="alternateUsernameAllowed" required="false">
<p>(boolean) By default, the jdbc-pool will ignore the
<a href="http://download.oracle.com/javase/6/docs/api/javax/sql/DataSource.html#getConnection(java.lang.String,%20java.lang.String)"><code>DataSource.getConnection(username,password)</code></a>
@@ -504,6 +515,18 @@
<attributes>
</attributes>
</subsection>
+ <subsection name="org.apache.tomcat.jdbc.pool.interceptor.QueryTimeoutInterceptor">
+ <p>Automatically calls java.sql.Statement.setQueryTimeout(seconds) when a new statement is created.
+ The pool itself doesn't timeout the query, it is still up to the JDBC driver to enforce query timeouts.
+ </p>
+ <attributes>
+ <attribute name="queryTimeout" required="true">
+ <p>(int as String) The number of seconds to set for the query timeout
+ The default value is <code>1000</code> milliseconds.
+ </p>
+ </attribute>
+ </attributes>
+ </subsection>
<subsection name="org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport">
<p>Keeps track of query performance and issues log entries when queries exceed a time threshold of fail.
The log level used is <code>WARN</code>
Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java?rev=1204203&r1=1204202&r2=1204203&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java (original)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java Sun Nov 20 18:24:16 2011
@@ -777,6 +777,28 @@ public class ConnectionPool {
}
}
}
+ /**
+ * return true if the connection TX termination succeeded
+ * @param con
+ * @return
+ */
+ protected boolean terminateTransaction(PooledConnection con) {
+ try {
+ boolean autocommit = con.getConnection().getAutoCommit();
+ if (!autocommit) {
+ if (this.getPoolProperties().getRollbackOnReturn()) {
+ con.getConnection().rollback();
+ } else if (this.getPoolProperties().getCommitOnReturn()) {
+ con.getConnection().commit();
+ }
+ }
+ return true;
+ } catch (SQLException x) {
+ log.warn("Unable to terminate transaction, connection will be closed.",x);
+ return false;
+ }
+
+ }
/**
* Determines if a connection should be closed upon return to the pool.
@@ -788,6 +810,7 @@ public class ConnectionPool {
if (con.isDiscarded()) return true;
if (isClosed()) return true;
if (!con.validate(action)) return true;
+ if (!terminateTransaction(con)) return true;
if (getPoolProperties().getMaxAge()>0 ) {
return (System.currentTimeMillis()-con.getLastConnected()) > getPoolProperties().getMaxAge();
} else {
Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java?rev=1204203&r1=1204202&r2=1204203&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java (original)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java Sun Nov 20 18:24:16 2011
@@ -1194,4 +1194,32 @@ public class DataSourceProxy implements
getPoolProperties().setAlternateUsernameAllowed(alternateUsernameAllowed);
}
+ /**
+ * {@inheritDoc}
+ */
+ public void setCommitOnReturn(boolean commitOnReturn) {
+ getPoolProperties().setCommitOnReturn(commitOnReturn);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean getCommitOnReturn() {
+ return getPoolProperties().getCommitOnReturn();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setRollbackOnReturn(boolean rollbackOnReturn) {
+ getPoolProperties().setRollbackOnReturn(rollbackOnReturn);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean getRollbackOnReturn() {
+ return getPoolProperties().getRollbackOnReturn();
+ }
+
}
Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java?rev=1204203&r1=1204202&r2=1204203&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java (original)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java Sun Nov 20 18:24:16 2011
@@ -793,6 +793,34 @@ public interface PoolConfiguration {
* false if it is to be ignored.
*/
public void setAlternateUsernameAllowed(boolean alternateUsernameAllowed);
+ /**
+ * Set to true if you want the connection pool to commit any pending transaction when a connection is returned.
+ * The default value is false, as this could result in committing data.
+ * This parameter is only looked at if the {@link java.sql.Connection#getAutoCommit()} returns false
+ * @param commitOnReturn set to true if the pool should call {@link java.sql.Connection#commit()} when a connection is returned to the pool.
+ * Default is false
+ */
+ public void setCommitOnReturn(boolean commitOnReturn);
+
+ /**
+ * @see {@link PoolConfiguration#setCommitOnReturn(boolean)}
+ * @return
+ */
+ public boolean getCommitOnReturn();
+
+ /**
+ * Set to true if you want the connection pool to rollback any pending transaction when a connection is returned.
+ * The default value is false, as this could result in committing data.
+ * This parameter is only looked at if the {@link java.sql.Connection#getAutoCommit()} returns false
+ * @param rollbackOnReturn set to true if the pool should call {@link java.sql.Connection#rollback()} when a connection is returned to the pool.
+ * Default is false
+ */
+ public void setRollbackOnReturn(boolean rollbackOnReturn);
+
+ /**
+ * @see {@link PoolConfiguration#setRollbackOnReturn(boolean)}
+ * @return
+ */
+ public boolean getRollbackOnReturn();
-
-}
\ No newline at end of file
+}
Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java?rev=1204203&r1=1204202&r2=1204203&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java (original)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java Sun Nov 20 18:24:16 2011
@@ -83,12 +83,13 @@ public class PoolProperties implements P
protected Object dataSource = null;
protected String dataSourceJNDI = null;
protected boolean alternateUsernameAllowed = false;
-
-
+ protected boolean commitOnReturn = false;
+ protected boolean rollbackOnReturn = false;
+
+
/**
* {@inheritDoc}
*/
-
@Override
public void setAbandonWhenPercentageFull(int percentage) {
if (percentage<0) abandonWhenPercentageFull = 0;
@@ -99,7 +100,6 @@ public class PoolProperties implements P
/**
* {@inheritDoc}
*/
-
@Override
public int getAbandonWhenPercentageFull() {
return abandonWhenPercentageFull;
@@ -108,7 +108,6 @@ public class PoolProperties implements P
/**
* {@inheritDoc}
*/
-
@Override
public boolean isFairQueue() {
return fairQueue;
@@ -117,7 +116,6 @@ public class PoolProperties implements P
/**
* {@inheritDoc}
*/
-
@Override
public void setFairQueue(boolean fairQueue) {
this.fairQueue = fairQueue;
@@ -126,7 +124,6 @@ public class PoolProperties implements P
/**
* {@inheritDoc}
*/
-
@Override
public boolean isAccessToUnderlyingConnectionAllowed() {
return accessToUnderlyingConnectionAllowed;
@@ -1164,4 +1161,32 @@ public class PoolProperties implements P
this.alternateUsernameAllowed = alternateUsernameAllowed;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setCommitOnReturn(boolean commitOnReturn) {
+ this.commitOnReturn = commitOnReturn;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean getCommitOnReturn() {
+ return this.commitOnReturn;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setRollbackOnReturn(boolean rollbackOnReturn) {
+ this.rollbackOnReturn = rollbackOnReturn;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean getRollbackOnReturn() {
+ return this.rollbackOnReturn;
+ }
}
Added: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/QueryTimeoutInterceptor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/QueryTimeoutInterceptor.java?rev=1204203&view=auto
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/QueryTimeoutInterceptor.java (added)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/QueryTimeoutInterceptor.java Sun Nov 20 18:24:16 2011
@@ -0,0 +1,39 @@
+package org.apache.tomcat.jdbc.pool.interceptor;
+
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorProperty;
+
+public class QueryTimeoutInterceptor extends AbstractCreateStatementInterceptor {
+ private static Log log = LogFactory.getLog(QueryTimeoutInterceptor.class);
+ int timeout;
+
+ @Override
+ public void setProperties(Map<String,InterceptorProperty> properties) {
+ super.setProperties(properties);
+ timeout = properties.get("queryTimeout").getValueAsInt(-1);
+ }
+
+ @Override
+ public Object createStatement(Object proxy, Method method, Object[] args, Object statement, long time) {
+ if (statement instanceof Statement && timeout > 0) {
+ Statement s = (Statement)statement;
+ try {
+ s.setQueryTimeout(timeout);
+ }catch (SQLException x) {
+ log.warn("[QueryTimeoutInterceptor] Unable to set query timeout:"+x.getMessage(),x);
+ }
+ }
+ return statement;
+ }
+
+ @Override
+ public void closeInvoked() {
+ }
+
+}
Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java?rev=1204203&r1=1204202&r2=1204203&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java (original)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java Sun Nov 20 18:24:16 2011
@@ -744,7 +744,34 @@ public class ConnectionPool extends Noti
public void setValidator(Validator validator) {
//noop
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setCommitOnReturn(boolean commitOnReturn) {
+ getPoolProperties().setCommitOnReturn(commitOnReturn);
+ }
+ /**
+ * {@inheritDoc}
+ */
+ public boolean getCommitOnReturn() {
+ return getPoolProperties().getCommitOnReturn();
+ }
+ /**
+ * {@inheritDoc}
+ */
+ public void setRollbackOnReturn(boolean rollbackOnReturn) {
+ getPoolProperties().setRollbackOnReturn(rollbackOnReturn);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean getRollbackOnReturn() {
+ return getPoolProperties().getRollbackOnReturn();
+ }
+
}
Added: tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestQueryTimeoutInterceptor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestQueryTimeoutInterceptor.java?rev=1204203&view=auto
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestQueryTimeoutInterceptor.java (added)
+++ tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestQueryTimeoutInterceptor.java Sun Nov 20 18:24:16 2011
@@ -0,0 +1,66 @@
+/*
+ * 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.test;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import javax.sql.PooledConnection;
+
+
+import org.apache.tomcat.jdbc.pool.interceptor.QueryTimeoutInterceptor;
+import org.apache.tomcat.jdbc.test.driver.Driver;
+
+
+public class TestQueryTimeoutInterceptor extends DefaultTestCase {
+
+ private static final int iterations = 500000; //(new Random(System.currentTimeMillis())).nextInt(1000000)+100000;
+ public TestQueryTimeoutInterceptor(String name) {
+ super(name);
+ }
+
+ public void testTimeout() throws Exception {
+ long start = System.currentTimeMillis();
+ int timeout = 10;
+ int withoutuser =10;
+ int withuser = withoutuser;
+ this.init();
+ this.datasource.setMaxActive(withuser+withoutuser);
+ this.datasource.setJdbcInterceptors(QueryTimeoutInterceptor.class.getName()+"(queryTimeout="+timeout+")");
+ this.datasource.setDriverClassName(Driver.class.getName());
+ this.datasource.setUrl("jdbc:tomcat:test");
+ Connection con = this.datasource.getConnection();
+ Statement st = con.createStatement();
+ assertEquals(st.getClass().getName(),timeout,st.getQueryTimeout());
+ st.close();
+ st = con.prepareStatement("");
+ assertEquals(st.getClass().getName(),timeout,st.getQueryTimeout());
+ st.close();
+ st = con.prepareCall("");
+ assertEquals(st.getClass().getName(),timeout,st.getQueryTimeout());
+ st.close();
+ con.close();
+ }
+}
Modified: tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java?rev=1204203&r1=1204202&r2=1204203&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java (original)
+++ tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java Sun Nov 20 18:24:16 2011
@@ -41,7 +41,7 @@ import java.util.Calendar;
import java.util.Map;
public class Statement implements CallableStatement {
-
+ int timeout=-1;
@Override
public Array getArray(int parameterIndex) throws SQLException {
// TODO Auto-generated method stub
@@ -1179,7 +1179,7 @@ public class Statement implements Callab
@Override
public int getQueryTimeout() throws SQLException {
// TODO Auto-generated method stub
- return 0;
+ return timeout;
}
@Override
@@ -1275,6 +1275,7 @@ public class Statement implements Callab
@Override
public void setQueryTimeout(int seconds) throws SQLException {
// TODO Auto-generated method stub
+ this.timeout = seconds;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org