Author: fhanik
Date: Tue Mar 20 15:45:19 2012
New Revision: 1302948
URL: http://svn.apache.org/viewvc?rev=1302948&view=rev
Log:
https://issues.apache.org/bugzilla/show_bug.cgi?id=52002 add in ability to
configure pool so that connections can not be reused
Added:
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java
Modified:
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/JdbcInterceptor.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
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=1302948&r1=1302947&r2=1302948&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
Tue Mar 20 15:45:19 2012
@@ -312,7 +312,12 @@ public class ConnectionPool {
getProxyConstructor(con.getXAConnection() != null);
//create the proxy
//TODO possible optimization, keep track if this connection was
returned properly, and don't generate a new facade
- Connection connection =
(Connection)proxyClassConstructor.newInstance(new Object[] { handler });
+ Connection connection = null;
+ if (getPoolProperties().getUseDisposableConnectionFacade() ) {
+ connection = (Connection)proxyClassConstructor.newInstance(new
Object[] { new DisposableConnectionFacade(handler) });
+ } else {
+ connection = (Connection)proxyClassConstructor.newInstance(new
Object[] {handler});
+ }
//return the connection
return connection;
}catch (Exception x) {
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=1302948&r1=1302947&r2=1302948&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
Tue Mar 20 15:45:19 2012
@@ -1226,4 +1226,20 @@ public class DataSourceProxy implements
return getPoolProperties().getRollbackOnReturn();
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setUseDisposableConnectionFacade(boolean
useDisposableConnectionFacade) {
+
getPoolProperties().setUseDisposableConnectionFacade(useDisposableConnectionFacade);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean getUseDisposableConnectionFacade() {
+ return getPoolProperties().getUseDisposableConnectionFacade();
+ }
+
}
Added:
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java?rev=1302948&view=auto
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
(added)
+++
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
Tue Mar 20 15:45:19 2012
@@ -0,0 +1,69 @@
+/*
+ * 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;
+
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+
+/**
+ * A DisposableConnectionFacade object is the top most interceptor that wraps
an object of type
+ * {@link PooledConnection}. The ProxyCutOffConnection intercepts two methods:
+ * <ul>
+ * <li>{@link java.sql.Connection#close()} - returns the connection to the
pool then breaks the link between cutoff and the next interceptor. May be
called multiple times.</li>
+ * <li>{@link java.lang.Object#toString()} - returns a custom string for
this object</li>
+ * </ul>
+ * By default method comparisons is done on a String reference level, unless
the {@link PoolConfiguration#setUseEquals(boolean)} has been called
+ * with a <code>true</code> argument.
+ * @author Kevin Grainer
+ */
+public class DisposableConnectionFacade extends JdbcInterceptor {
+ protected DisposableConnectionFacade(JdbcInterceptor interceptor) throws
SQLException {
+ setUseEquals(interceptor.isUseEquals());
+ setNext(interceptor);
+ }
+
+ @Override
+ public void reset(ConnectionPool parent, PooledConnection con) {
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
+ if (compare(ISCLOSED_VAL, method) && getNext() == null) {
+ return Boolean.TRUE;
+ }
+ if (compare(CLOSE_VAL, method) && getNext() == null) {
+ return null;
+ }
+
+ try {
+ return super.invoke(proxy, method, args);
+ } catch (NullPointerException e) {
+ if (getNext() == null) {
+ if (compare(TOSTRING_VAL, method)) {
+ return "DisposableConnectionFacade[null]";
+ }
+ throw new SQLException("Connection has already been closed.");
+ }
+
+ throw e;
+ } finally {
+ if (compare(CLOSE_VAL, method)) {
+ setNext(null);
+ }
+ }
+ }
+}
Modified:
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
Tue Mar 20 15:45:19 2012
@@ -70,7 +70,7 @@ public abstract class JdbcInterceptor im
/**
* The next interceptor in the chain
*/
- private JdbcInterceptor next = null;
+ private volatile JdbcInterceptor next = null;
/**
* Property that decides how we do string comparison, default is to use
* {@link String#equals(Object)}. If set to <code>false</code> then the
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=1302948&r1=1302947&r2=1302948&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
Tue Mar 20 15:45:19 2012
@@ -821,4 +821,18 @@ public interface PoolConfiguration {
*/
public boolean getRollbackOnReturn();
+ /**
+ * If set to true, the connection will be wrapped with facade that will
disallow the connection to be used after
+ * {@link java.sql.Connection#close()} is called. If set to true, after
{@link java.sql.Connection#close()} all calls except
+ * {@link java.sql.Connection#close()} and {@link
java.sql.Connection#isClosed()} will throw an exception.
+ * @param useDisposableConnectionFacade
+ */
+ public void setUseDisposableConnectionFacade(boolean
useDisposableConnectionFacade);
+ /**
+ * Returns true if this connection pool is configured to use a connection
facade to prevent re-use of connection after
+ * {@link java.sql.Connection#close()} has been invoked
+ * @return true if {@link java.sql.Connection#close()} has been invoked.
+ */
+ public boolean getUseDisposableConnectionFacade();
+
}
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=1302948&r1=1302947&r2=1302948&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
Tue Mar 20 15:45:19 2012
@@ -86,6 +86,7 @@ public class PoolProperties implements P
protected boolean alternateUsernameAllowed = false;
protected boolean commitOnReturn = false;
protected boolean rollbackOnReturn = false;
+ protected boolean useDisposableConnectionFacade;
/**
@@ -1194,4 +1195,29 @@ public class PoolProperties implements P
public boolean getRollbackOnReturn() {
return this.rollbackOnReturn;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setUseDisposableConnectionFacade(boolean
useDisposableConnectionFacade) {
+ this.useDisposableConnectionFacade = useDisposableConnectionFacade;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean getUseDisposableConnectionFacade() {
+ return useDisposableConnectionFacade;
+ }
+
+ @Override
+ protected Object clone() throws CloneNotSupportedException {
+ // TODO Auto-generated method stub
+ return super.clone();
+ }
+
+
+
}
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=1302948&r1=1302947&r2=1302948&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
Tue Mar 20 15:45:19 2012
@@ -777,5 +777,22 @@ public class ConnectionPool extends Noti
return getPoolProperties().getRollbackOnReturn();
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setUseDisposableConnectionFacade(boolean
useDisposableConnectionFacade) {
+
getPoolProperties().setUseDisposableConnectionFacade(useDisposableConnectionFacade);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean getUseDisposableConnectionFacade() {
+ return getPoolProperties().getUseDisposableConnectionFacade();
+ }
+
+
}
Added:
tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java?rev=1302948&view=auto
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java
(added)
+++
tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java
Tue Mar 20 15:45:19 2012
@@ -0,0 +1,67 @@
+/*
+ * 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 org.apache.tomcat.jdbc.test.driver.Driver;
+
+public class MultipleCloseTest extends DefaultTestCase {
+
+ public MultipleCloseTest(String name) {
+ super(name);
+ }
+
+ @Override
+ public org.apache.tomcat.jdbc.pool.DataSource createDefaultDataSource() {
+ org.apache.tomcat.jdbc.pool.DataSource ds =
super.createDefaultDataSource();
+ ds.getPoolProperties().setDriverClassName(Driver.class.getName());
+ ds.getPoolProperties().setUrl(Driver.url);
+ ds.getPoolProperties().setInitialSize(0);
+ ds.getPoolProperties().setMaxIdle(1);
+ ds.getPoolProperties().setMinIdle(1);
+ ds.getPoolProperties().setMaxActive(1);
+ ds.getPoolProperties().setUseDisposableConnectionFacade(true);
+ return ds;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ Driver.reset();
+ super.tearDown();
+ }
+
+ public void testClosedConnectionsNotReused() throws Exception {
+ this.init();
+
+ Connection con1 = datasource.getConnection();
+
+ // A new connection is open
+ assertFalse(con1.isClosed());
+
+ con1.close();
+
+ // Confirm that a closed connection is closed
+ assertTrue(con1.isClosed());
+
+ // Open a new connection (This will re-use the previous pooled
connection)
+ datasource.getConnection();
+
+ // A connection, once closed, should stay closed
+ assertTrue(con1.isClosed());
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]