From 1352771e3fe08ea5657102f2a99e817f9b4c447e Mon Sep 17 00:00:00 2001 From: wenshao Date: Thu, 29 Dec 2011 23:04:03 +0800 Subject: [PATCH] user clearDefines optimize Oracle PrepareStatement Cache memoery use --- .../alibaba/druid/pool/DruidDataSource.java | 4 +- .../druid/pool/DruidDataSourceMBean.java | 10 ---- .../com/alibaba/druid/pool/OracleUtils.java | 17 ++++++ .../druid/pool/PoolableConnection.java | 8 +++ .../druid/pool/PoolablePreparedStatement.java | 4 ++ .../druid/pool/PreparedStatementHolder.java | 10 ++-- .../druid/pool/PreparedStatementPool.java | 4 +- .../pool/TestOraclePreparedStatement.java | 59 +++++++++++++++++++ .../pool/TestOracle_DruidDataSource.java | 1 + 9 files changed, 98 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/pool/OracleUtils.java create mode 100644 src/test/java/com/alibaba/druid/pool/TestOraclePreparedStatement.java diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 54ad7dbba7..149c25ea24 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -1279,8 +1279,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat if (entryIndex++ != 0) { buf.append(","); } - buf.append("\n\t\t{reuseCount:"); - buf.append(entry.getValue().getReusedCount()); + buf.append("\n\t\t{hitCount:"); + buf.append(entry.getValue().getHitCount()); buf.append(",sql:\""); buf.append(entry.getKey().getSql()); buf.append("\""); diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSourceMBean.java b/src/main/java/com/alibaba/druid/pool/DruidDataSourceMBean.java index 7c5138f2ae..6e7889bc77 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSourceMBean.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSourceMBean.java @@ -56,18 +56,8 @@ public interface DruidDataSourceMBean extends DruidAbstractDataSourceMBean { void setPoolPreparedStatements(boolean poolPreparedStatements); - /** - * ActiveCount峰值 - * - * @return - */ int getActivePeak(); - /** - * PoolingCount峰值 - * - * @return - */ int getPoolingPeak(); Date getActivePeakTime(); diff --git a/src/main/java/com/alibaba/druid/pool/OracleUtils.java b/src/main/java/com/alibaba/druid/pool/OracleUtils.java new file mode 100644 index 0000000000..9a0f9883ec --- /dev/null +++ b/src/main/java/com/alibaba/druid/pool/OracleUtils.java @@ -0,0 +1,17 @@ +package com.alibaba.druid.pool; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +import oracle.jdbc.driver.OracleStatement; + + +public class OracleUtils { + public static void clearDefines(PoolablePreparedStatement stmt) throws SQLException { + PreparedStatement raw = stmt.getRawPreparedStatement(); + if (raw instanceof OracleStatement) { + OracleStatement oracleStmt = (OracleStatement) raw; + oracleStmt.clearDefines(); + } + } +} diff --git a/src/main/java/com/alibaba/druid/pool/PoolableConnection.java b/src/main/java/com/alibaba/druid/pool/PoolableConnection.java index 43846a6f7d..9e9fcecab0 100644 --- a/src/main/java/com/alibaba/druid/pool/PoolableConnection.java +++ b/src/main/java/com/alibaba/druid/pool/PoolableConnection.java @@ -96,6 +96,10 @@ public class PoolableConnection implements PooledConnection, Connection { throw new SQLException("Error", t); } + + private boolean isOracle() { + return "oracle".equals(holder.getDataSource().getDbType()); + } void closePoolableStatement(PoolablePreparedStatement stmt) throws SQLException { if (this.holder == null) { @@ -118,6 +122,10 @@ public class PoolableConnection implements PooledConnection, Connection { stmt.clearResultSet(); holder.removeTrace(stmt); stmt.setClosed(true); // soft set close + + if (stmt.getHitCount() == 0 && isOracle()) { + OracleUtils.clearDefines(stmt); + } } else { stmt.closeInternal(); holder.getDataSource().incrementClosedPreparedStatementCount(); diff --git a/src/main/java/com/alibaba/druid/pool/PoolablePreparedStatement.java b/src/main/java/com/alibaba/druid/pool/PoolablePreparedStatement.java index eb093de546..7972191cd0 100644 --- a/src/main/java/com/alibaba/druid/pool/PoolablePreparedStatement.java +++ b/src/main/java/com/alibaba/druid/pool/PoolablePreparedStatement.java @@ -81,6 +81,10 @@ public class PoolablePreparedStatement extends PoolableStatement implements Prep public PreparedStatementHolder getPreparedStatementHolder() { return holder; } + + public int getHitCount() { + return holder.getHitCount(); + } public void setFetchSize(int rows) throws SQLException { currentFetchSize = rows; diff --git a/src/main/java/com/alibaba/druid/pool/PreparedStatementHolder.java b/src/main/java/com/alibaba/druid/pool/PreparedStatementHolder.java index 66928915a9..0acc6b61dd 100644 --- a/src/main/java/com/alibaba/druid/pool/PreparedStatementHolder.java +++ b/src/main/java/com/alibaba/druid/pool/PreparedStatementHolder.java @@ -26,7 +26,7 @@ public final class PreparedStatementHolder { private final PreparedStatementKey key; private final PreparedStatement statement; - private int useCount = 0; + private int hitCount = 0; public PreparedStatementHolder(PreparedStatementKey key, PreparedStatement stmt){ this.key = key; @@ -41,12 +41,12 @@ public final class PreparedStatementHolder { return key; } - public void incrementReusedCount() { - useCount++; + public void incrementHitCount() { + hitCount++; } - public int getReusedCount() { - return useCount; + public int getHitCount() { + return hitCount; } } diff --git a/src/main/java/com/alibaba/druid/pool/PreparedStatementPool.java b/src/main/java/com/alibaba/druid/pool/PreparedStatementPool.java index a6cc6d3b5f..3b1e7667f7 100644 --- a/src/main/java/com/alibaba/druid/pool/PreparedStatementPool.java +++ b/src/main/java/com/alibaba/druid/pool/PreparedStatementPool.java @@ -49,7 +49,7 @@ public class PreparedStatementPool { PreparedStatementHolder holder = map.get(key); if (holder != null) { - holder.incrementReusedCount(); + holder.incrementHitCount(); dataSource.incrementCachedPreparedStatementHitCount(); } else { dataSource.incrementCachedPreparedStatementMissCount(); @@ -70,7 +70,7 @@ public class PreparedStatementPool { if (oldHolder != null) { dataSource.closePreapredStatement(oldHolder); } else { - if (holder.getReusedCount() == 0) { + if (holder.getHitCount() == 0) { dataSource.incrementCachedPreparedStatementCount(); } } diff --git a/src/test/java/com/alibaba/druid/pool/TestOraclePreparedStatement.java b/src/test/java/com/alibaba/druid/pool/TestOraclePreparedStatement.java new file mode 100644 index 0000000000..f1087d6891 --- /dev/null +++ b/src/test/java/com/alibaba/druid/pool/TestOraclePreparedStatement.java @@ -0,0 +1,59 @@ +package com.alibaba.druid.pool; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; + +import junit.framework.TestCase; +import oracle.jdbc.driver.OraclePreparedStatement; + +import com.alibaba.druid.util.JdbcUtils; + +public class TestOraclePreparedStatement extends TestCase { + + private String jdbcUrl; + private String user; + private String password; + + public void setUp() throws Exception { + jdbcUrl = "jdbc:oracle:thin:@10.20.149.85:1521:ocnauto"; + // jdbcUrl = "jdbc:oracle:thin:@20.20.149.85:1521:ocnauto"; // error url + user = "alibaba"; + password = "ccbuauto"; + } + + public void test_0() throws Exception { + Class.forName(JdbcUtils.getDriverClassName(jdbcUrl)); + + Connection conn = DriverManager.getConnection(jdbcUrl, user, password); + + // ResultSet metaRs = conn.getMetaData().getTables(null, "ALIBABA", null, new String[] {"TABLE"}); + // JdbcUtils.printResultSet(metaRs); + // metaRs.close(); + + OraclePreparedStatement oracleStmt = null; + PreparedStatement stmt = conn.prepareStatement("SELECT ? FROM DUAL"); + oracleStmt = (OraclePreparedStatement) stmt; + { + + stmt.setString(1, "aaa"); + ResultSet rs = stmt.executeQuery(); + rs.next(); + + rs.close(); + + oracleStmt.clearDefines(); + } + { + stmt.setString(1, "bbb"); + ResultSet rs = stmt.executeQuery(); + rs.next(); + + rs.close(); + stmt.close(); + } + + conn.close(); + } +} diff --git a/src/test/java/com/alibaba/druid/pool/TestOracle_DruidDataSource.java b/src/test/java/com/alibaba/druid/pool/TestOracle_DruidDataSource.java index 64a22703e5..f7a6e3a405 100644 --- a/src/test/java/com/alibaba/druid/pool/TestOracle_DruidDataSource.java +++ b/src/test/java/com/alibaba/druid/pool/TestOracle_DruidDataSource.java @@ -29,6 +29,7 @@ public class TestOracle_DruidDataSource extends TestCase { public void test_0() throws Exception { final String SQL = "SELECT SYSDATE FROM DUAL"; final DruidDataSource dataSource = new DruidDataSource(); + dataSource.setInitialSize(1); dataSource.setUrl(jdbcUrl); dataSource.setUsername(user); dataSource.setPassword(password);