From 705552efd3f0d7877bbc14a617f55e3d6f236ce4 Mon Sep 17 00:00:00 2001 From: wenshao Date: Mon, 13 Aug 2012 21:29:45 +0800 Subject: [PATCH] add pscache testcase --- .../druid/pool/PreparedStatementHolder.java | 14 +- .../druid/pool/PreparedStatementPool.java | 11 +- .../alibaba/druid/bvt/pool/PSCacheTest3.java | 178 ++++++++++++++++++ 3 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/pool/PSCacheTest3.java diff --git a/src/main/java/com/alibaba/druid/pool/PreparedStatementHolder.java b/src/main/java/com/alibaba/druid/pool/PreparedStatementHolder.java index c95ab38686..92d16d696e 100644 --- a/src/main/java/com/alibaba/druid/pool/PreparedStatementHolder.java +++ b/src/main/java/com/alibaba/druid/pool/PreparedStatementHolder.java @@ -36,6 +36,7 @@ public final class PreparedStatementHolder { private boolean enterOracleImplicitCache = false; private int inUseCount = 0; + private boolean pooling = false; public PreparedStatementHolder(PreparedStatementKey key, PreparedStatement stmt){ this.key = key; @@ -99,12 +100,21 @@ public final class PreparedStatementHolder { public void incrementInUseCount() { inUseCount++; } - + public void decrementInUseCount() { inUseCount--; } - + public int getInUseCount() { return inUseCount; } + + public boolean isPooling() { + return pooling; + } + + public void setPooling(boolean pooling) { + this.pooling = pooling; + } + } diff --git a/src/main/java/com/alibaba/druid/pool/PreparedStatementPool.java b/src/main/java/com/alibaba/druid/pool/PreparedStatementPool.java index 9cc2608ab9..1aa893d71b 100644 --- a/src/main/java/com/alibaba/druid/pool/PreparedStatementPool.java +++ b/src/main/java/com/alibaba/druid/pool/PreparedStatementPool.java @@ -57,7 +57,7 @@ public class PreparedStatementPool { if (holder.isInUse() && (!dataSource.isSharePreparedStatements())) { return null; } - + holder.incrementHitCount(); dataSource.incrementCachedPreparedStatementHitCount(); if (holder.isEnterOracleImplicitCache()) { @@ -88,6 +88,7 @@ public class PreparedStatementPool { PreparedStatementHolder oldHolder = map.put(key, holder); if (oldHolder != null && oldHolder != holder) { + oldHolder.setPooling(false); dataSource.closePreapredStatement(oldHolder); } else { if (holder.getHitCount() == 0) { @@ -95,6 +96,7 @@ public class PreparedStatementPool { } } + holder.setPooling(true); } public void clear() throws SQLException { @@ -109,10 +111,11 @@ public class PreparedStatementPool { } private void closeRemovedStatement(PreparedStatementHolder holder) throws SQLException { + holder.setPooling(false); if (holder.isInUse()) { return; } - + if (holder.isEnterOracleImplicitCache()) { OracleUtils.exitImplicitCacheToClose(holder.getStatement()); } @@ -125,6 +128,10 @@ public class PreparedStatementPool { return map; } + public int size() { + return this.map.size(); + } + public class LRUCache extends LinkedHashMap { private static final long serialVersionUID = 1L; diff --git a/src/test/java/com/alibaba/druid/bvt/pool/PSCacheTest3.java b/src/test/java/com/alibaba/druid/bvt/pool/PSCacheTest3.java new file mode 100644 index 0000000000..5598549baa --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/PSCacheTest3.java @@ -0,0 +1,178 @@ +package com.alibaba.druid.bvt.pool; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.pool.ConnectionHolder; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; +import com.alibaba.druid.pool.DruidPooledPreparedStatement; +import com.alibaba.druid.pool.PreparedStatementHolder; +import com.alibaba.druid.pool.PreparedStatementPool; +import com.alibaba.druid.util.JdbcUtils; + +public class PSCacheTest3 extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:x1"); + dataSource.setPoolPreparedStatements(true); + dataSource.setMaxOpenPreparedStatements(3); + } + + protected void tearDown() throws Exception { + JdbcUtils.close(dataSource); + } + + public void test_pscache() throws Exception { + DruidPooledConnection conn = dataSource.getConnection(); + + ConnectionHolder holder = conn.getConnectionHolder(); + PreparedStatementPool stmtPool = holder.getStatementPool(); + + final String sql_0 = "select 0"; + final String sql_1 = "select 1"; + final String sql_2 = "select 2"; + final String sql_3 = "select 3"; + final String sql_4 = "select 4"; + + Assert.assertEquals(0, stmtPool.size()); + + PreparedStatementHolder stmtHoler_0; + PreparedStatementHolder stmtHoler_1; + PreparedStatementHolder stmtHoler_2; + PreparedStatementHolder stmtHoler_3; + PreparedStatementHolder stmtHoler_4; + + // sql_0连续执行两次 + { + DruidPooledPreparedStatement stmt_0 = (DruidPooledPreparedStatement) conn.prepareStatement(sql_0); + + Assert.assertFalse(stmt_0.getPreparedStatementHolder().isPooling()); + + stmt_0.close(); + Assert.assertEquals(1, stmtPool.size()); + Assert.assertTrue(stmt_0.getPreparedStatementHolder().isPooling()); + } + { + DruidPooledPreparedStatement stmt_0 = (DruidPooledPreparedStatement) conn.prepareStatement(sql_0); + Assert.assertEquals(1, stmtPool.size()); + Assert.assertTrue(stmt_0.getPreparedStatementHolder().isInUse()); + Assert.assertTrue(stmt_0.getPreparedStatementHolder().isPooling()); + + stmt_0.close(); + + Assert.assertFalse(stmt_0.getPreparedStatementHolder().isInUse()); + Assert.assertTrue(stmt_0.getPreparedStatementHolder().isPooling()); + Assert.assertEquals(1, stmtPool.size()); + } + + DruidPooledPreparedStatement stmt_0 = (DruidPooledPreparedStatement) conn.prepareStatement(sql_0); + + stmtHoler_0 = stmt_0.getPreparedStatementHolder(); + + Assert.assertTrue(stmtHoler_0.isInUse()); + Assert.assertTrue(stmtHoler_0.isPooling()); + + stmt_0.execute(); + + { + DruidPooledPreparedStatement stmt_1 = (DruidPooledPreparedStatement) conn.prepareStatement(sql_1); + Assert.assertEquals(1, stmtPool.size()); + + stmtHoler_1 = stmt_1.getPreparedStatementHolder(); + + Assert.assertTrue(stmt_1.getPreparedStatementHolder().isInUse()); + Assert.assertFalse(stmt_1.getPreparedStatementHolder().isPooling()); + + stmt_1.close(); + + Assert.assertFalse(stmt_1.getPreparedStatementHolder().isInUse()); + Assert.assertTrue(stmt_1.getPreparedStatementHolder().isPooling()); + Assert.assertTrue(stmt_1.getPreparedStatementHolder().isPooling()); + Assert.assertEquals(2, stmtPool.size()); + } + + Assert.assertTrue(stmtHoler_0.isPooling()); + Assert.assertTrue(stmtHoler_1.isPooling()); + + { + DruidPooledPreparedStatement stmt_2 = (DruidPooledPreparedStatement) conn.prepareStatement(sql_2); + Assert.assertEquals(2, stmtPool.size()); + + stmtHoler_2 = stmt_2.getPreparedStatementHolder(); + + Assert.assertTrue(stmt_2.getPreparedStatementHolder().isInUse()); + Assert.assertFalse(stmt_2.getPreparedStatementHolder().isPooling()); + + stmt_2.close(); + + Assert.assertFalse(stmt_2.getPreparedStatementHolder().isInUse()); + Assert.assertTrue(stmt_2.getPreparedStatementHolder().isPooling()); + Assert.assertTrue(stmt_2.getPreparedStatementHolder().isPooling()); + Assert.assertEquals(3, stmtPool.size()); + } + + Assert.assertTrue(stmtHoler_0.isPooling()); + Assert.assertTrue(stmtHoler_1.isPooling()); + Assert.assertTrue(stmtHoler_2.isPooling()); + + { + DruidPooledPreparedStatement stmt_3 = (DruidPooledPreparedStatement) conn.prepareStatement(sql_3); + Assert.assertEquals(3, stmtPool.size()); + + stmtHoler_3 = stmt_3.getPreparedStatementHolder(); + + Assert.assertTrue(stmt_3.getPreparedStatementHolder().isInUse()); + Assert.assertFalse(stmt_3.getPreparedStatementHolder().isPooling()); + + stmt_3.close(); + + Assert.assertFalse(stmt_3.getPreparedStatementHolder().isInUse()); + Assert.assertTrue(stmt_3.getPreparedStatementHolder().isPooling()); + Assert.assertTrue(stmt_3.getPreparedStatementHolder().isPooling()); + Assert.assertEquals(3, stmtPool.size()); + } + + + Assert.assertFalse(stmtHoler_0.isPooling()); + Assert.assertTrue(stmtHoler_1.isPooling()); + Assert.assertTrue(stmtHoler_2.isPooling()); + Assert.assertTrue(stmtHoler_3.isPooling()); + + { + DruidPooledPreparedStatement stmt_4 = (DruidPooledPreparedStatement) conn.prepareStatement(sql_4); + Assert.assertEquals(3, stmtPool.size()); + + stmtHoler_4 = stmt_4.getPreparedStatementHolder(); + + Assert.assertTrue(stmt_4.getPreparedStatementHolder().isInUse()); + Assert.assertFalse(stmt_4.getPreparedStatementHolder().isPooling()); + + stmt_4.close(); + + Assert.assertFalse(stmt_4.getPreparedStatementHolder().isInUse()); + Assert.assertTrue(stmt_4.getPreparedStatementHolder().isPooling()); + Assert.assertTrue(stmt_4.getPreparedStatementHolder().isPooling()); + Assert.assertEquals(3, stmtPool.size()); + } + + Assert.assertFalse(stmtHoler_0.isPooling()); + Assert.assertFalse(stmtHoler_1.isPooling()); + Assert.assertTrue(stmtHoler_2.isPooling()); + Assert.assertTrue(stmtHoler_3.isPooling()); + Assert.assertTrue(stmtHoler_4.isPooling()); + + stmt_0.close(); + + Assert.assertTrue(stmtHoler_0.isPooling()); + Assert.assertFalse(stmtHoler_1.isPooling()); + Assert.assertFalse(stmtHoler_2.isPooling()); + Assert.assertTrue(stmtHoler_3.isPooling()); + Assert.assertTrue(stmtHoler_4.isPooling()); + + conn.close(); + } +}