From 5bbf3312ee7ad28764e50a1cbd423910af017922 Mon Sep 17 00:00:00 2001 From: wenshao Date: Fri, 30 Dec 2011 14:58:08 +0800 Subject: [PATCH] optimized for oracle --- .../com/alibaba/druid/pool/OracleUtils.java | 46 ------------ .../druid/pool/PoolableConnection.java | 3 +- .../druid/pool/PoolablePreparedStatement.java | 1 + .../vendor/OracleValidConnectionChecker.java | 50 +++---------- .../com/alibaba/druid/util/OracleUtils.java | 75 +++++++++++++++++++ .../druid/bvt/util/OracleUtilsTest.java | 34 +++++++++ .../druid/pool/benckmark/Oracle_Case4.java | 34 +++++---- 7 files changed, 139 insertions(+), 104 deletions(-) delete mode 100644 src/main/java/com/alibaba/druid/pool/OracleUtils.java create mode 100644 src/main/java/com/alibaba/druid/util/OracleUtils.java create mode 100644 src/test/java/com/alibaba/druid/bvt/util/OracleUtilsTest.java diff --git a/src/main/java/com/alibaba/druid/pool/OracleUtils.java b/src/main/java/com/alibaba/druid/pool/OracleUtils.java deleted file mode 100644 index c9cb0bd221..0000000000 --- a/src/main/java/com/alibaba/druid/pool/OracleUtils.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.alibaba.druid.pool; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; - -import oracle.jdbc.OracleConnection; -import oracle.jdbc.OracleStatement; - -public class OracleUtils { - - public static void clearDefines(PoolablePreparedStatement stmt) throws SQLException { - OracleStatement oracleStmt = stmt.unwrap(OracleStatement.class); - oracleStmt.clearDefines(); - } - - public static int getRowPrefetch(PreparedStatement stmt) throws SQLException { - OracleStatement oracleStmt = stmt.unwrap(OracleStatement.class); - return oracleStmt.getRowPrefetch(); - } - - public static void setRowPrefetch(PreparedStatement stmt, int value) throws SQLException { - OracleStatement oracleStmt = stmt.unwrap(OracleStatement.class); - oracleStmt.setRowPrefetch(value); - } - - public static void setDefaultRowPrefetch(Connection conn, int value) throws SQLException { - OracleConnection oracleConn = conn.unwrap(OracleConnection.class); - oracleConn.setDefaultRowPrefetch(value); - } - - public static int getDefaultRowPrefetch(Connection conn, int value) throws SQLException { - OracleConnection oracleConn = conn.unwrap(OracleConnection.class); - return oracleConn.getDefaultRowPrefetch(); - } - - public static void cancel(Connection conn) throws SQLException { - OracleConnection oracleConn = conn.unwrap(OracleConnection.class); - oracleConn.cancel(); - } - - public static void pingDatabase(Connection conn) throws SQLException { - OracleConnection oracleConn = conn.unwrap(OracleConnection.class); - oracleConn.pingDatabase(); - } -} diff --git a/src/main/java/com/alibaba/druid/pool/PoolableConnection.java b/src/main/java/com/alibaba/druid/pool/PoolableConnection.java index 2771f4d6a1..71d59fb9aa 100644 --- a/src/main/java/com/alibaba/druid/pool/PoolableConnection.java +++ b/src/main/java/com/alibaba/druid/pool/PoolableConnection.java @@ -44,6 +44,7 @@ import com.alibaba.druid.logging.Log; import com.alibaba.druid.logging.LogFactory; import com.alibaba.druid.pool.PoolablePreparedStatement.PreparedStatementKey; import com.alibaba.druid.pool.PreparedStatementPool.MethodType; +import com.alibaba.druid.util.OracleUtils; import com.alibaba.druid.util.TransactionInfo; /** @@ -126,7 +127,7 @@ public class PoolableConnection implements PooledConnection, Connection { stmt.setClosed(true); // soft set close - if (stmt.getHitCount() == 0 && isOracle()) { + if (stmt.getHitCount() < 2 && isOracle()) { OracleUtils.clearDefines(stmt); } } else { diff --git a/src/main/java/com/alibaba/druid/pool/PoolablePreparedStatement.java b/src/main/java/com/alibaba/druid/pool/PoolablePreparedStatement.java index 6b4365430b..952a315fc7 100644 --- a/src/main/java/com/alibaba/druid/pool/PoolablePreparedStatement.java +++ b/src/main/java/com/alibaba/druid/pool/PoolablePreparedStatement.java @@ -38,6 +38,7 @@ import java.util.Arrays; import java.util.Calendar; import com.alibaba.druid.pool.PreparedStatementPool.MethodType; +import com.alibaba.druid.util.OracleUtils; /** * @author wenshao diff --git a/src/main/java/com/alibaba/druid/pool/vendor/OracleValidConnectionChecker.java b/src/main/java/com/alibaba/druid/pool/vendor/OracleValidConnectionChecker.java index ee811ad066..c3f54862a2 100644 --- a/src/main/java/com/alibaba/druid/pool/vendor/OracleValidConnectionChecker.java +++ b/src/main/java/com/alibaba/druid/pool/vendor/OracleValidConnectionChecker.java @@ -22,37 +22,24 @@ package com.alibaba.druid.pool.vendor; import java.io.Serializable; -import java.lang.reflect.Method; import java.sql.Connection; -import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Statement; import com.alibaba.druid.logging.Log; import com.alibaba.druid.logging.LogFactory; import com.alibaba.druid.pool.PoolableConnection; import com.alibaba.druid.pool.ValidConnectionChecker; import com.alibaba.druid.proxy.jdbc.ConnectionProxy; -import com.alibaba.druid.util.DruidLoaderUtils; -import com.alibaba.druid.util.JdbcUtils; +import com.alibaba.druid.util.OracleUtils; public class OracleValidConnectionChecker implements ValidConnectionChecker, Serializable { - private static final long serialVersionUID = -2227528634302168877L; + private static final long serialVersionUID = -2227528634302168877L; - private static final Log LOG = LogFactory.getLog(OracleValidConnectionChecker.class); - - private final Class clazz; - private final Method ping; - private final static Object[] params = new Object[] { new Integer(5000) }; + private static final Log LOG = LogFactory.getLog(OracleValidConnectionChecker.class); public OracleValidConnectionChecker(){ - try { - clazz = DruidLoaderUtils.loadClass("oracle.jdbc.driver.OracleConnection"); - ping = clazz.getMethod("pingDatabase", new Class[] { Integer.TYPE }); - } catch (Exception e) { - throw new RuntimeException("Unable to resolve pingDatabase method:", e); - } + } public boolean isValidConnection(Connection conn, String valiateQuery, int validationQueryTimeout) { @@ -78,33 +65,14 @@ public class OracleValidConnectionChecker implements ValidConnectionChecker, Ser conn = ((ConnectionProxy) conn).getConnectionRaw(); } - // unwrap - if (clazz.isAssignableFrom(conn.getClass())) { - Integer status = (Integer) ping.invoke(conn, params); + int status = OracleUtils.pingDatabase(conn); - // Error - if (status.intValue() < 0) { - return false; - } - - return true; + // Error + if (status < 0) { + return false; } - Statement stmt = null; - ResultSet rs = null; - try { - stmt = conn.createStatement(); - rs = stmt.executeQuery(valiateQuery); - return true; - } catch (SQLException e) { - return false; - } catch (Exception e) { - LOG.warn("Unexpected error in ping", e); - return false; - } finally { - JdbcUtils.close(rs); - JdbcUtils.close(stmt); - } + return true; } catch (Exception e) { LOG.warn("Unexpected error in pingDatabase", e); } diff --git a/src/main/java/com/alibaba/druid/util/OracleUtils.java b/src/main/java/com/alibaba/druid/util/OracleUtils.java new file mode 100644 index 0000000000..e3337dd43f --- /dev/null +++ b/src/main/java/com/alibaba/druid/util/OracleUtils.java @@ -0,0 +1,75 @@ +package com.alibaba.druid.util; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import oracle.jdbc.OracleConnection; +import oracle.jdbc.OracleResultSet; +import oracle.jdbc.OracleStatement; +import oracle.sql.ROWID; + +import com.alibaba.druid.pool.PoolablePreparedStatement; + +public class OracleUtils { + + public static void clearDefines(PoolablePreparedStatement stmt) throws SQLException { + OracleStatement oracleStmt = stmt.unwrap(OracleStatement.class); + oracleStmt.clearDefines(); + } + + public static int getRowPrefetch(PreparedStatement stmt) throws SQLException { + OracleStatement oracleStmt = stmt.unwrap(OracleStatement.class); + return oracleStmt.getRowPrefetch(); + } + + public static void setRowPrefetch(PreparedStatement stmt, int value) throws SQLException { + OracleStatement oracleStmt = stmt.unwrap(OracleStatement.class); + oracleStmt.setRowPrefetch(value); + } + + public static void setDefaultRowPrefetch(Connection conn, int value) throws SQLException { + OracleConnection oracleConn = unwrap(conn); + oracleConn.setDefaultRowPrefetch(value); + } + + public static int getDefaultRowPrefetch(Connection conn, int value) throws SQLException { + OracleConnection oracleConn = unwrap(conn); + return oracleConn.getDefaultRowPrefetch(); + } + + public static void cancel(Connection conn) throws SQLException { + OracleConnection oracleConn = unwrap(conn); + oracleConn.cancel(); + } + + public static int pingDatabase(Connection conn) throws SQLException { + OracleConnection oracleConn = unwrap(conn); + return oracleConn.pingDatabase(); + } + + public static void openProxySession(Connection conn, int type, java.util.Properties prop) throws SQLException { + OracleConnection oracleConn = unwrap(conn); + oracleConn.openProxySession(type, prop); + } + + public static int getDefaultExecuteBatch(Connection conn) throws SQLException { + OracleConnection oracleConn = unwrap(conn); + return oracleConn.getDefaultExecuteBatch(); + } + + public static OracleConnection unwrap(Connection conn) throws SQLException { + if (conn instanceof OracleConnection) { + return (OracleConnection) conn; + } + + return conn.unwrap(OracleConnection.class); + } + + public static ROWID getROWID(ResultSet rs, int columnIndex) throws SQLException { + OracleResultSet oracleResultSet = rs.unwrap(OracleResultSet.class); + return oracleResultSet.getROWID(columnIndex); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/util/OracleUtilsTest.java b/src/test/java/com/alibaba/druid/bvt/util/OracleUtilsTest.java new file mode 100644 index 0000000000..59b0dd69a9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/util/OracleUtilsTest.java @@ -0,0 +1,34 @@ +package com.alibaba.druid.bvt.util; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import junit.framework.TestCase; +import oracle.jdbc.OracleConnection; + +import org.junit.Assert; + +import com.alibaba.druid.util.OracleUtils; + +public class OracleUtilsTest extends TestCase { + public void test_oracle() throws Exception { + InvocationHandler handler = new InvocationHandler() { + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (method.getName().equals("pingDatabase")) { + return 1; + } + + return null; + } + + }; + OracleConnection conn = (OracleConnection) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] {OracleConnection.class}, handler); + + Assert.assertNotNull(OracleUtils.unwrap(conn)); + + Assert.assertEquals(1, OracleUtils.pingDatabase(conn)); + } +} diff --git a/src/test/java/com/alibaba/druid/pool/benckmark/Oracle_Case4.java b/src/test/java/com/alibaba/druid/pool/benckmark/Oracle_Case4.java index 80c7e533c5..066dacc292 100644 --- a/src/test/java/com/alibaba/druid/pool/benckmark/Oracle_Case4.java +++ b/src/test/java/com/alibaba/druid/pool/benckmark/Oracle_Case4.java @@ -21,21 +21,21 @@ import com.alibaba.druid.util.JdbcUtils; public class Oracle_Case4 extends TestCase { - private String jdbcUrl; - private String user; - private String password; - private String driverClass; - private int maxIdle = 40; - private int maxActive = 50; - private int maxWait = 5000; - private String validationQuery = "SELECT 1 FROM DUAL"; - private int threadCount = 1; - private int loopCount = 3; - final int LOOP_COUNT = 1000 * 10; - private boolean testOnBorrow = false; - private boolean preparedStatementCache = true; - - private final String SQL = "SELECT MEMBER_ID FROM WP_ORDERS WHERE ID = ?"; + private String jdbcUrl; + private String user; + private String password; + private String driverClass; + private int maxIdle = 40; + private int maxActive = 50; + private int maxWait = 5000; + private String validationQuery = "SELECT 1 FROM DUAL"; + private int threadCount = 1; + private int loopCount = 3; + final int LOOP_COUNT = 1000 * 1; + private boolean testOnBorrow = false; + private boolean preparedStatementCache = true; + + private final String SQL = "SELECT MEMBER_ID FROM WP_ORDERS WHERE ID = ?"; protected void setUp() throws Exception { jdbcUrl = "jdbc:oracle:thin:@10.20.149.85:1521:ocnauto"; @@ -44,13 +44,14 @@ public class Oracle_Case4 extends TestCase { driverClass = "oracle.jdbc.driver.OracleDriver"; } - public void xtest_0() throws Exception { + public void test_0() throws Exception { DruidDataSource dataSource = new DruidDataSource(); dataSource.setMaxActive(maxActive); dataSource.setMaxIdle(maxIdle); dataSource.setMaxWait(maxWait); dataSource.setPoolPreparedStatements(preparedStatementCache); + dataSource.setMaxOpenPreparedStatements(10); dataSource.setDriverClassName(driverClass); dataSource.setUrl(jdbcUrl); dataSource.setUsername(user); @@ -74,6 +75,7 @@ public class Oracle_Case4 extends TestCase { dataSource.setMaxIdle(maxIdle); dataSource.setMaxWait(maxWait); dataSource.setPoolPreparedStatements(preparedStatementCache); + dataSource.setMaxOpenPreparedStatements(10); dataSource.setDriverClassName(driverClass); dataSource.setUrl(jdbcUrl); dataSource.setUsername(user);