diff --git a/README b/README new file mode 100644 index 0000000000..18d8c362f1 --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +mvn install:install-file -Dfile=lib/oracle/11.2.0.3/ojdbc5_g.jar -DgroupId=com.oracle -DartifactId=ojdbc5 -Dversion=11.2.0.3 -Dpackaging=jar -DgeneratePom=true +mvn install:install-file -Dfile=lib/oracle/11.2.0.3/ojdbc6_g.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.3 -Dpackaging=jar -DgeneratePom=true \ No newline at end of file diff --git a/lib/oracle/11.2.0.3/ojdbc5_g.jar b/lib/oracle/11.2.0.3/ojdbc5_g.jar new file mode 100644 index 0000000000..6f2828cb7e Binary files /dev/null and b/lib/oracle/11.2.0.3/ojdbc5_g.jar differ diff --git a/lib/oracle/11.2.0.3/ojdbc6_g.jar b/lib/oracle/11.2.0.3/ojdbc6_g.jar new file mode 100644 index 0000000000..c5ceb5acb8 Binary files /dev/null and b/lib/oracle/11.2.0.3/ojdbc6_g.jar differ diff --git a/pom.xml b/pom.xml index 9b1179d19a..83f894b2ec 100644 --- a/pom.xml +++ b/pom.xml @@ -205,12 +205,12 @@ 5.1.12 test + - oracle - oracle-jdbc - 10.1.0.2.0 - test - true + com.oracle + ojdbc5 + 11.2.0.3 + provided diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index f9ccfb1f4f..473dd0e608 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -290,6 +290,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat if ("oracle".equals(this.dbType)) { isOracle = true; + + if (driver.getMajorVersion() < 10) { + throw new SQLException("not support oracle driver " + driver.getMajorVersion() + "." + driver.getMinorVersion()); + } } String realDriverClassName = driver.getClass().getName(); diff --git a/src/main/java/com/alibaba/druid/pool/OracleUtils.java b/src/main/java/com/alibaba/druid/pool/OracleUtils.java index de3ed1affb..c9cb0bd221 100644 --- a/src/main/java/com/alibaba/druid/pool/OracleUtils.java +++ b/src/main/java/com/alibaba/druid/pool/OracleUtils.java @@ -5,7 +5,7 @@ import java.sql.PreparedStatement; import java.sql.SQLException; import oracle.jdbc.OracleConnection; -import oracle.jdbc.driver.OracleStatement; +import oracle.jdbc.OracleStatement; public class OracleUtils { @@ -30,11 +30,17 @@ public class OracleUtils { } public static int getDefaultRowPrefetch(Connection conn, int value) throws SQLException { - if (conn instanceof OracleConnection) { - OracleConnection oracleConn = (OracleConnection) conn; - return oracleConn.getDefaultRowPrefetch(); - } + OracleConnection oracleConn = conn.unwrap(OracleConnection.class); + return oracleConn.getDefaultRowPrefetch(); + } - return -1; + 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/PoolablePreparedStatement.java b/src/main/java/com/alibaba/druid/pool/PoolablePreparedStatement.java index 03667524c2..6b4365430b 100644 --- a/src/main/java/com/alibaba/druid/pool/PoolablePreparedStatement.java +++ b/src/main/java/com/alibaba/druid/pool/PoolablePreparedStatement.java @@ -173,7 +173,7 @@ public class PoolablePreparedStatement extends PoolableStatement implements Prep incrementExecuteCount(); transactionRecord(sql); - oracleSetRowPrefetch(); + // oracleSetRowPrefetch(); try { ResultSet rs = stmt.executeQuery(); @@ -429,7 +429,7 @@ public class PoolablePreparedStatement extends PoolableStatement implements Prep incrementExecuteCount(); transactionRecord(sql); - oracleSetRowPrefetch(); + // oracleSetRowPrefetch(); try { return stmt.execute(); @@ -438,7 +438,7 @@ public class PoolablePreparedStatement extends PoolableStatement implements Prep } } - private void oracleSetRowPrefetch() throws SQLException { + protected void oracleSetRowPrefetch() throws SQLException { if (!conn.isOracle()) { return; } @@ -446,7 +446,7 @@ public class PoolablePreparedStatement extends PoolableStatement implements Prep if (holder.getHitCount() == 0) { return; } - + int fetchRowPeak = holder.getFetchRowPeak(); if (fetchRowPeak < 0) { diff --git a/src/test/java/com/alibaba/druid/pool/TestDruidOraclePreparedStatement.java b/src/test/java/com/alibaba/druid/pool/TestDruidOraclePreparedStatement.java index 722c3c1a16..5f81aae01e 100644 --- a/src/test/java/com/alibaba/druid/pool/TestDruidOraclePreparedStatement.java +++ b/src/test/java/com/alibaba/druid/pool/TestDruidOraclePreparedStatement.java @@ -1,13 +1,11 @@ package com.alibaba.druid.pool; import java.sql.Connection; -import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.Statement; import junit.framework.TestCase; -import oracle.jdbc.OracleConnection; -import oracle.jdbc.driver.OraclePreparedStatement; import com.alibaba.druid.util.JdbcUtils; @@ -41,6 +39,28 @@ public class TestDruidOraclePreparedStatement extends TestCase { Class.forName(JdbcUtils.getDriverClassName(jdbcUrl)); + { + Connection conn = dataSource.getConnection(); + + ResultSet metaRs = conn.getMetaData().getTables(null, "ALIBABA", null, new String[] { "TABLE" }); + JdbcUtils.printResultSet(metaRs); + metaRs.close(); + + conn.close(); + } + + { + Connection conn = dataSource.getConnection(); + Statement stmt = conn.createStatement(); + + ResultSet rs = stmt.executeQuery("SELECT * FROM WP_ORDERS"); + JdbcUtils.printResultSet(rs); + rs.close(); + + stmt.close(); + conn.close(); + } + for (int i = 0; i < 3; ++i) { Connection conn = dataSource.getConnection(); diff --git a/src/test/java/com/alibaba/druid/pool/TestOraclePreparedStatement.java b/src/test/java/com/alibaba/druid/pool/TestOraclePreparedStatement.java index 745cd949f8..b511ca0fc7 100644 --- a/src/test/java/com/alibaba/druid/pool/TestOraclePreparedStatement.java +++ b/src/test/java/com/alibaba/druid/pool/TestOraclePreparedStatement.java @@ -7,7 +7,7 @@ import java.sql.ResultSet; import junit.framework.TestCase; import oracle.jdbc.OracleConnection; -import oracle.jdbc.driver.OraclePreparedStatement; +import oracle.jdbc.OraclePreparedStatement; import com.alibaba.druid.util.JdbcUtils; @@ -37,15 +37,15 @@ public class TestOraclePreparedStatement extends TestCase { int fetchRowSize = oracleConn.getDefaultRowPrefetch(); - String sql = "SELECT * FROM WS_OFFER WHERE ROWNUM <= ?"; + String sql = "SELECT * FROM WP_ORDERS WHERE ID <= ?"; OraclePreparedStatement oracleStmt = null; PreparedStatement stmt = conn.prepareStatement(sql); oracleStmt = (OraclePreparedStatement) stmt; - oracleStmt.setRowPrefetch(1); + oracleStmt.setRowPrefetch(10); { - stmt.setInt(1, 1); + stmt.setInt(1, 327); ResultSet rs = stmt.executeQuery(); while (rs.next()) { 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 new file mode 100644 index 0000000000..80c7e533c5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/pool/benckmark/Oracle_Case4.java @@ -0,0 +1,160 @@ +package com.alibaba.druid.pool.benckmark; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.text.NumberFormat; +import java.util.concurrent.CountDownLatch; + +import javax.sql.DataSource; + +import junit.framework.TestCase; + +import org.apache.commons.dbcp.BasicDataSource; +import org.springframework.util.Assert; + +import com.alibaba.druid.TestUtil; +import com.alibaba.druid.pool.DruidDataSource; +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 = ?"; + + protected void setUp() throws Exception { + jdbcUrl = "jdbc:oracle:thin:@10.20.149.85:1521:ocnauto"; + user = "alibaba"; + password = "ccbuauto"; + driverClass = "oracle.jdbc.driver.OracleDriver"; + } + + public void xtest_0() throws Exception { + DruidDataSource dataSource = new DruidDataSource(); + + dataSource.setMaxActive(maxActive); + dataSource.setMaxIdle(maxIdle); + dataSource.setMaxWait(maxWait); + dataSource.setPoolPreparedStatements(preparedStatementCache); + dataSource.setDriverClassName(driverClass); + dataSource.setUrl(jdbcUrl); + dataSource.setUsername(user); + dataSource.setPassword(password); + dataSource.setValidationQuery(validationQuery); + dataSource.setTestOnBorrow(testOnBorrow); + + // printTables(dataSource); + // printWP_ORDERS(dataSource); + + for (int i = 0; i < loopCount; ++i) { + p0(dataSource, "druid", threadCount); + } + System.out.println(); + } + + public void test_1() throws Exception { + final BasicDataSource dataSource = new BasicDataSource(); + + dataSource.setMaxActive(maxActive); + dataSource.setMaxIdle(maxIdle); + dataSource.setMaxWait(maxWait); + dataSource.setPoolPreparedStatements(preparedStatementCache); + dataSource.setDriverClassName(driverClass); + dataSource.setUrl(jdbcUrl); + dataSource.setUsername(user); + dataSource.setPassword(password); + dataSource.setValidationQuery(validationQuery); + dataSource.setTestOnBorrow(testOnBorrow); + + for (int i = 0; i < loopCount; ++i) { + p0(dataSource, "dbcp", threadCount); + } + System.out.println(); + } + + private void printWP_ORDERS(DruidDataSource dataSource) throws SQLException { + Connection conn = dataSource.getConnection(); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM WP_ORDERS"); + + JdbcUtils.printResultSet(rs); + + rs.close(); + stmt.close(); + conn.close(); + } + + protected void printTables(DruidDataSource dataSource) throws SQLException { + Connection conn = dataSource.getConnection(); + + ResultSet rs = conn.getMetaData().getTables(null, "ALIBABA", null, new String[] { "TABLE" }); + JdbcUtils.printResultSet(rs); + rs.close(); + + conn.close(); + } + + private void p0(final DataSource dataSource, String name, int threadCount) throws Exception { + + final CountDownLatch startLatch = new CountDownLatch(1); + final CountDownLatch endLatch = new CountDownLatch(threadCount); + for (int i = 0; i < threadCount; ++i) { + Thread thread = new Thread() { + + public void run() { + try { + startLatch.await(); + + for (int i = 0; i < LOOP_COUNT; ++i) { + Connection conn = dataSource.getConnection(); + String sql = SQL; // + " AND ROWNUM <= " + (i % 20 + 1); + PreparedStatement stmt = conn.prepareStatement(sql); + stmt.setInt(1, 337); + ResultSet rs = stmt.executeQuery(); + while (rs.next()) { + + } + // Assert.isTrue(!rs.isClosed()); + rs.close(); + // Assert.isTrue(!stmt.isClosed()); + stmt.close(); + Assert.isTrue(stmt.isClosed()); + conn.close(); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + endLatch.countDown(); + } + }; + thread.start(); + } + long startMillis = System.currentTimeMillis(); + long startYGC = TestUtil.getYoungGC(); + long startFullGC = TestUtil.getFullGC(); + startLatch.countDown(); + endLatch.await(); + + long millis = System.currentTimeMillis() - startMillis; + long ygc = TestUtil.getYoungGC() - startYGC; + long fullGC = TestUtil.getFullGC() - startFullGC; + + System.out.println("thread " + threadCount + " " + name + " millis : " + + NumberFormat.getInstance().format(millis) + ", YGC " + ygc + " FGC " + fullGC); + } +}