Author: fhanik
Date: Fri Apr 16 00:02:53 2010
New Revision: 934651
URL: http://svn.apache.org/viewvc?rev=934651&view=rev
Log:
Add in statement cache
Added:
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestStatementCache.java
(with props)
Modified:
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/AbstractCreateStatementInterceptor.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/interceptor/StatementCache.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/StatementDecoratorInterceptor.java
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=934651&r1=934650&r2=934651&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 Apr 16 00:02:53 2010
@@ -19,6 +19,7 @@ package org.apache.tomcat.jdbc.pool;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.HashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.juli.logging.Log;
@@ -106,6 +107,8 @@ public class PooledConnection {
* The parent
*/
protected ConnectionPool parent;
+
+ private HashMap<Object, Object> attributes = new HashMap<Object, Object>();
/**
* Weak reference to cache the list of interceptors for this connection
@@ -598,5 +601,9 @@ public class PooledConnection {
public boolean isReleased() {
return released.get();
}
+
+ public HashMap<Object,Object> getAttributes() {
+ return attributes;
+ }
}
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractCreateStatementInterceptor.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractCreateStatementInterceptor.java?rev=934651&r1=934650&r2=934651&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractCreateStatementInterceptor.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractCreateStatementInterceptor.java
Fri Apr 16 00:02:53 2010
@@ -35,7 +35,7 @@ public abstract class AbstractCreateSta
protected static final String PREPARE_STATEMENT = "prepareStatement";
protected static final int PREPARE_STATEMENT_IDX = 1;
protected static final String PREPARE_CALL = "prepareCall";
- protected static final int PREPARE_IDX = 2;
+ protected static final int PREPARE_CALL_IDX = 2;
protected static final String[] STATEMENT_TYPES = {CREATE_STATEMENT,
PREPARE_STATEMENT, PREPARE_CALL};
protected static final int STATEMENT_TYPE_COUNT =
STATEMENT_TYPES.length;
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=934651&r1=934650&r2=934651&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 Apr 16 00:02:53 2010
@@ -182,7 +182,7 @@ public abstract class AbstractQueryRepor
}else if (compare(PREPARE_CALL,name)) {
//prepareCall
sql = (String)args[0];
- constructor =
getConstructor(PREPARE_IDX,CallableStatement.class);
+ constructor =
getConstructor(PREPARE_CALL_IDX,CallableStatement.class);
prepareCall(sql,time);
}else {
//do nothing, might be a future unsupported method
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/StatementCache.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/StatementCache.java?rev=934651&r1=934650&r2=934651&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/StatementCache.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/StatementCache.java
Fri Apr 16 00:02:53 2010
@@ -18,7 +18,6 @@ package org.apache.tomcat.jdbc.pool.inte
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
@@ -36,16 +35,37 @@ public class StatementCache extends Stat
protected static final String[] CALLABLE_TYPE = new String[]
{PREPARE_CALL};
protected static final String[] PREPARED_TYPE = new String[]
{PREPARE_STATEMENT};
protected static final String[] NO_TYPE = new String[] {};
+
+ protected static final String STATEMENT_CACHE_ATTR =
StatementCache.class.getName() + ".cache";
/*begin properties for the statement cache*/
private boolean cachePrepared = true;
private boolean cacheCallable = false;
private int maxCacheSize = 50;
- private ConnectionPool parent;
private PooledConnection pcon;
private String[] types;
+ public boolean isCachePrepared() {
+ return cachePrepared;
+ }
+
+ public boolean isCacheCallable() {
+ return cacheCallable;
+ }
+
+ public int getMaxCacheSize() {
+ return maxCacheSize;
+ }
+
+ public String[] getTypes() {
+ return types;
+ }
+
+ public AtomicInteger getCacheSize() {
+ return cacheSize;
+ }
+
public void setProperties(Map<String, InterceptorProperty> properties) {
super.setProperties(properties);
InterceptorProperty p = properties.get("prepared");
@@ -86,35 +106,36 @@ public class StatementCache extends Stat
/*begin the actual statement cache*/
- private static ConcurrentHashMap<PooledConnection,
ConcurrentHashMap<String,StatementProxy>> statementCache =
- new ConcurrentHashMap<PooledConnection,
ConcurrentHashMap<String,StatementProxy>>();
-
-
public void reset(ConnectionPool parent, PooledConnection con) {
super.reset(parent, con);
if (parent==null) {
cacheSize = null;
- this.parent = null;
this.pcon = null;
} else {
cacheSize = cacheSizeMap.get(parent);
- this.parent = parent;
this.pcon = con;
+ if (!pcon.getAttributes().containsKey(STATEMENT_CACHE_ATTR)) {
+ ConcurrentHashMap<String,CachedStatement> cache = new
ConcurrentHashMap<String, CachedStatement>();
+ pcon.getAttributes().put(STATEMENT_CACHE_ATTR,cache);
+ }
}
}
public void disconnected(ConnectionPool parent, PooledConnection con,
boolean finalizing) {
- ConcurrentHashMap<String,StatementProxy> statements =
statementCache.get(con);
+ ConcurrentHashMap<String,CachedStatement> statements =
+
(ConcurrentHashMap<String,CachedStatement>)con.getAttributes().get(STATEMENT_CACHE_ATTR);
+
if (statements!=null) {
- for (Map.Entry<String, StatementProxy> p : statements.entrySet()) {
+ for (Map.Entry<String, CachedStatement> p : statements.entrySet())
{
closeStatement(p.getValue());
}
statements.clear();
}
+
super.disconnected(parent, con, finalizing);
}
- public void closeStatement(StatementProxy st) {
+ public void closeStatement(CachedStatement st) {
try {
if (st==null) return;
if (((PreparedStatement)st).isClosed()) return;
@@ -125,39 +146,59 @@ public class StatementCache extends Stat
}
}
+ @Override
+ protected Object createDecorator(Object proxy, Method method, Object[]
args,
+ Object statement, Constructor<?>
constructor, String sql)
+ throws InstantiationException, IllegalAccessException,
InvocationTargetException {
+ boolean process = process(this.types, method, false);
+ if (process) {
+ Object result = null;
+ CachedStatement statementProxy = new
CachedStatement((Statement)statement,sql);
+ result = constructor.newInstance(new Object[] { statementProxy });
+ statementProxy.setActualProxy(result);
+ statementProxy.setConnection(proxy);
+ statementProxy.setConstructor(constructor);
+ return result;
+ } else {
+ return super.createDecorator(proxy, method, args, statement,
constructor, sql);
+ }
+ }
+
+
public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
if (compare(CLOSE_VAL,method)) {
return super.invoke(proxy, method, args);
} else {
- boolean process = false;
- process = process(this.types, method, process);
-
- if (process) {
- //check the cache
- //if (isCached) {
-
- //} else {
+ boolean process = process(this.types, method, false);
+ if (process && args.length>0 && args[0] instanceof String) {
+ CachedStatement statement = isCached((String)args[0]);
+ if (statement!=null) {
+ //remove it from the cache since it is used
+ removeStatement(statement);
+ return statement.getActualProxy();
+ } else {
return super.invoke(proxy, method, args);
- //}
+ }
} else {
return super.invoke(proxy,method,args);
}
}
}
- public boolean isCached(String sql) {
- ConcurrentHashMap<String,StatementProxy> cache =
statementCache.get(pcon);
- return cache.containsKey(sql);
+ public CachedStatement isCached(String sql) {
+ ConcurrentHashMap<String,CachedStatement> cache =
+
(ConcurrentHashMap<String,CachedStatement>)pcon.getAttributes().get(STATEMENT_CACHE_ATTR);
+ return cache.get(sql);
}
- public boolean cacheStatement(StatementProxy proxy) {
- ConcurrentHashMap<String,StatementProxy> cache =
statementCache.get(pcon);
+ public boolean cacheStatement(CachedStatement proxy) {
+ ConcurrentHashMap<String,CachedStatement> cache =
+
(ConcurrentHashMap<String,CachedStatement>)pcon.getAttributes().get(STATEMENT_CACHE_ATTR);
if (proxy.getSql()==null) {
return false;
} else if (cache.containsKey(proxy.getSql())) {
- cache.put(proxy.getSql(), proxy);
- return true;
+ return false;
} else if (cacheSize.get()>=maxCacheSize) {
return false;
} else if (cacheSize.incrementAndGet()>maxCacheSize) {
@@ -165,26 +206,55 @@ public class StatementCache extends Stat
return false;
} else {
//cache the statement
+ cache.put(proxy.getSql(), proxy);
return true;
}
}
+
+ public boolean removeStatement(CachedStatement proxy) {
+ ConcurrentHashMap<String,CachedStatement> cache =
+
(ConcurrentHashMap<String,CachedStatement>)pcon.getAttributes().get(STATEMENT_CACHE_ATTR);
+ if (cache.remove(proxy.getSql()) != null) {
+ cacheSize.decrementAndGet();
+ return true;
+ } else {
+ return false;
+ }
+ }
/*end the actual statement cache*/
- protected class StatementProxy extends
StatementDecoratorInterceptor.StatementProxy {
+ protected class CachedStatement extends
StatementDecoratorInterceptor.StatementProxy<Statement> {
boolean cached = false;
- public StatementProxy(Object parent, String sql) {
+ public CachedStatement(Statement parent, String sql) {
super(parent, sql);
- cached = cacheStatement(this);
}
-
- public void closeInvoked() {
- super.closedInvoked();
- if (cached) {
+
+ @Override
+ public void closedInvoked() {
+ //should we cache it
+ boolean shouldClose = true;
+ if (cacheSize.get() < maxCacheSize) {
//cache a proxy so that we don't reuse the facade
- StatementProxy proxy = new
StatementProxy(getDelegate(),getSql());
- proxy.setActualProxy(getActualProxy());
- proxy.setConnection(getConnection());
+ CachedStatement proxy = new
CachedStatement(getDelegate(),getSql());
+ try {
+ //create a new facade
+ Object actualProxy = getConstructor().newInstance(new
Object[] { proxy });
+ proxy.setActualProxy(actualProxy);
+ proxy.setConnection(getConnection());
+ proxy.setConstructor(getConstructor());
+ if (cacheStatement(proxy)) {
+ proxy.cached = true;
+ shouldClose = false;
+ }
+ } catch (Exception x) {
+ removeStatement(proxy);
+ }
+ }
+ closed = true;
+ delegate = null;
+ if (shouldClose) {
+ super.closedInvoked();
}
}
@@ -194,53 +264,6 @@ public class StatementCache extends Stat
((Statement)getDelegate()).close();
}
- public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
- // get the name of the method for comparison
- final String name = method.getName();
- // was close invoked?
- boolean close = compare(JdbcInterceptor.CLOSE_VAL, name);
- // allow close to be called multiple times
- if (close && closed)
- return null;
- // are we calling isClosed?
- if (compare(JdbcInterceptor.ISCLOSED_VAL, name))
- return Boolean.valueOf(closed);
- // if we are calling anything else, bail out
- if (closed)
- throw new SQLException("Statement closed.");
- if (name.equals("getConnection")){
- return getConnection();
- }
- boolean process = isExecuteQuery(method);
- // check to see if we are about to execute a query
- // if we are executing, get the current time
- Object result = null;
- try {
- if (cached && close) {
- //dont invoke actual close
- } else {
- // execute the query
- result = method.invoke(delegate, args);
- }
- } catch (Throwable t) {
- if (t instanceof InvocationTargetException) {
- InvocationTargetException it = (InvocationTargetException)
t;
- throw it.getCause() != null ? it.getCause() : it;
- } else {
- throw t;
- }
- }
- // perform close cleanup
- if (close) {
- closeInvoked();
- }
- if (process){
- Constructor<?> cons = getResultSetConstructor();
- result = cons.newInstance(new Object[]{new
ResultSetProxy(getActualProxy(), result)});
- }
- return result;
- }
-
}
}
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/StatementDecoratorInterceptor.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/StatementDecoratorInterceptor.java?rev=934651&r1=934650&r2=934651&view=diff
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/StatementDecoratorInterceptor.java
(original)
+++
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/StatementDecoratorInterceptor.java
Fri Apr 16 00:02:53 2010
@@ -94,7 +94,6 @@ public class StatementDecoratorIntercept
@Override
public Object createStatement(Object proxy, Method method, Object[] args,
Object statement, long time) {
try {
- Object result = null;
String name = method.getName();
Constructor<?> constructor = null;
String sql = null;
@@ -107,24 +106,32 @@ public class StatementDecoratorIntercept
sql = (String)args[0];
} else if (compare(PREPARE_CALL, name)) {
// prepareCall
- constructor = getConstructor(PREPARE_IDX,
CallableStatement.class);
+ constructor = getConstructor(PREPARE_CALL_IDX,
CallableStatement.class);
sql = (String)args[0];
} else {
// do nothing, might be a future unsupported method
// so we better bail out and let the system continue
return statement;
}
- StatementProxy statementProxy = new StatementProxy(statement,sql);
- result = constructor.newInstance(new Object[] { statementProxy });
- statementProxy.setActualProxy(result);
- statementProxy.setConnection(proxy);
- return result;
+ return createDecorator(proxy, method, args, statement,
constructor, sql);
} catch (Exception x) {
logger.warn("Unable to create statement proxy for slow query
report.", x);
}
return statement;
}
+ protected Object createDecorator(Object proxy, Method method, Object[]
args,
+ Object statement, Constructor<?>
constructor, String sql)
+ throws InstantiationException, IllegalAccessException,
InvocationTargetException {
+ Object result = null;
+ StatementProxy statementProxy = new
StatementProxy<Statement>((Statement)statement,sql);
+ result = constructor.newInstance(new Object[] { statementProxy });
+ statementProxy.setActualProxy(result);
+ statementProxy.setConnection(proxy);
+ statementProxy.setConnection(constructor);
+ return result;
+ }
+
protected boolean isExecuteQuery(String methodName) {
return EXECUTE_QUERY_TYPES[0].equals(methodName);
}
@@ -139,19 +146,20 @@ public class StatementDecoratorIntercept
* @author fhanik
*
*/
- protected class StatementProxy implements InvocationHandler {
+ protected class StatementProxy<T extends java.sql.Statement> implements
InvocationHandler {
protected boolean closed = false;
- protected Object delegate;
+ protected T delegate;
private Object actualProxy;
private Object connection;
private String sql;
+ private Constructor constructor;
- public StatementProxy(Object parent, String sql) {
- this.delegate = parent;
+ public StatementProxy(T delegate, String sql) {
+ this.delegate = delegate;
this.sql = sql;
}
- public Object getDelegate() {
+ public T getDelegate() {
return this.delegate;
}
@@ -173,26 +181,40 @@ public class StatementDecoratorIntercept
return this.actualProxy;
}
+
+ public Constructor getConstructor() {
+ return constructor;
+ }
+ public void setConstructor(Constructor constructor) {
+ this.constructor = constructor;
+ }
public void closedInvoked() {
+ if (getDelegate()!=null) {
+ try {
+ getDelegate().close();
+ }catch (SQLException ignore) {
+ }
+ }
closed = true;
delegate = null;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
- // get the name of the method for comparison
- final String name = method.getName();
+ if (compare(TOSTRING_VAL,method)) {
+ return toString();
+ }
// was close invoked?
- boolean close = compare(JdbcInterceptor.CLOSE_VAL, name);
+ boolean close = compare(CLOSE_VAL, method);
// allow close to be called multiple times
if (close && closed)
return null;
// are we calling isClosed?
- if (compare(JdbcInterceptor.ISCLOSED_VAL, name))
+ if (compare(ISCLOSED_VAL, method))
return Boolean.valueOf(closed);
// if we are calling anything else, bail out
if (closed)
throw new SQLException("Statement closed.");
- if (name.equals("getConnection")){
+ if (compare(GETCONNECTION_VAL,method)){
return connection;
}
boolean process = isExecuteQuery(method);
@@ -200,8 +222,13 @@ public class StatementDecoratorIntercept
// if we are executing, get the current time
Object result = null;
try {
- // execute the query
- result = method.invoke(delegate, args);
+ // perform close cleanup
+ if (close) {
+ closedInvoked();
+ } else {
+ // execute the query
+ result = method.invoke(delegate, args);
+ }
} catch (Throwable t) {
if (t instanceof InvocationTargetException) {
InvocationTargetException it = (InvocationTargetException)
t;
@@ -210,16 +237,26 @@ public class StatementDecoratorIntercept
throw t;
}
}
- // perform close cleanup
- if (close) {
- closeInvoked();
- }
if (process){
Constructor<?> cons = getResultSetConstructor();
result = cons.newInstance(new Object[]{new
ResultSetProxy(actualProxy, result)});
}
return result;
}
+
+ public String toString() {
+ StringBuffer buf = new
StringBuffer(StatementProxy.class.getName());
+ buf.append("[Proxy=");
+ buf.append(System.identityHashCode(this));
+ buf.append("; Sql=");
+ buf.append(getSql());
+ buf.append("; Delegate=");
+ buf.append(getDelegate());
+ buf.append("; Connection=");
+ buf.append(getConnection());
+ buf.append("]");
+ return buf.toString();
+ }
}
protected class ResultSetProxy implements InvocationHandler {
Added:
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestStatementCache.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestStatementCache.java?rev=934651&view=auto
==============================================================================
---
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestStatementCache.java
(added)
+++
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestStatementCache.java
Fri Apr 16 00:02:53 2010
@@ -0,0 +1,135 @@
+/*
+ * 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.PreparedStatement;
+
+import org.apache.tomcat.jdbc.pool.interceptor.StatementCache;
+
+public class TestStatementCache extends DefaultTestCase {
+
+
+ public TestStatementCache(String name) {
+ super(name);
+ }
+
+ private static volatile TestStatementCacheInterceptor interceptor = null;
+
+
+ @Override
+ protected void tearDown() throws Exception {
+ // TODO Auto-generated method stub
+ this.interceptor = null;
+ super.tearDown();
+ }
+
+
+
+
+ private void config(boolean cachePrepared, boolean cacheCallable, int max)
{
+
datasource.getPoolProperties().setJdbcInterceptors(TestStatementCacheInterceptor.class.getName()+
+
"(prepared="+cachePrepared+",callable="+cacheCallable+",max="+max+")");
+ }
+
+ public void testIsCacheEnabled() throws Exception {
+ init();
+ config(true,true,50);
+ datasource.getConnection().close();
+ assertNotNull("Interceptor was not created.", interceptor);
+ }
+
+ public void testCacheProperties() throws Exception {
+ init();
+ config(true,true,50);
+ datasource.getConnection().close();
+ assertEquals(true, interceptor.isCacheCallable());
+ assertEquals(true, interceptor.isCachePrepared());
+ assertEquals(50,interceptor.getMaxCacheSize());
+ }
+
+ public void testCacheProperties2() throws Exception {
+ init();
+ config(false,false,100);
+ datasource.getConnection().close();
+ assertEquals(false, interceptor.isCacheCallable());
+ assertEquals(false, interceptor.isCachePrepared());
+ assertEquals(100,interceptor.getMaxCacheSize());
+ }
+
+ public void testPreparedStatementCache() throws Exception {
+ init();
+ config(true,false,100);
+ Connection con = datasource.getConnection();
+ PreparedStatement ps1 = con.prepareStatement("select 1");
+ PreparedStatement ps2 = con.prepareStatement("select 1");
+ assertEquals(0,interceptor.getCacheSize().get());
+ ps1.close();
+ assertTrue(ps1.isClosed());
+ assertEquals(1,interceptor.getCacheSize().get());
+ PreparedStatement ps3 = con.prepareStatement("select 1");
+ assertEquals(0,interceptor.getCacheSize().get());
+ ps2.close();
+ assertTrue(ps2.isClosed());
+ ps3.close();
+ assertTrue(ps3.isClosed());
+ assertEquals(1,interceptor.getCacheSize().get());
+ }
+
+ public void testPreparedStatementCache2() throws Exception {
+ init();
+ config(false,false,100);
+ Connection con = datasource.getConnection();
+ PreparedStatement ps1 = con.prepareStatement("select 1");
+ PreparedStatement ps2 = con.prepareStatement("select 1");
+ assertEquals(0,interceptor.getCacheSize().get());
+ ps1.close();
+ assertTrue(ps1.isClosed());
+ assertEquals(0,interceptor.getCacheSize().get());
+ PreparedStatement ps3 = con.prepareStatement("select 1");
+ assertEquals(0,interceptor.getCacheSize().get());
+ ps2.close();
+ assertTrue(ps2.isClosed());
+ ps3.close();
+ assertTrue(ps3.isClosed());
+ assertEquals(0,interceptor.getCacheSize().get());
+ }
+
+ public void testCallableStatementCache() throws Exception {
+ }
+
+ public void testMaxCacheSize() throws Exception {
+ init();
+ config(true,false,100);
+ Connection con1 = datasource.getConnection();
+ Connection con2 = datasource.getConnection();
+ for (int i=0; i<120; i++) {
+ Connection con = (i%2==0)?con1:con2;
+ PreparedStatement ps = con.prepareStatement("select "+i);
+ ps.close();
+ }
+ assertEquals(100,interceptor.getCacheSize().get());
+ }
+
+
+ public static class TestStatementCacheInterceptor extends StatementCache {
+ public TestStatementCacheInterceptor() {
+ TestStatementCache.interceptor = this;
+ }
+ }
+
+}
Propchange:
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestStatementCache.java
------------------------------------------------------------------------------
svn:eol-style = native
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]