diff --git a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java index 71df20bac6..4899b6921b 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java @@ -21,7 +21,9 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.Driver; +import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -633,6 +635,85 @@ public abstract class DruidAbstractDataSource implements DataSource, DataSourceP } } + public void validateConnection(Connection conn) throws SQLException { + String query = getValidationQuery(); + if (conn.isClosed()) { + throw new SQLException("validateConnection: connection closed"); + } + if (null != query) { + Statement stmt = null; + ResultSet rset = null; + try { + stmt = conn.createStatement(); + if (getValidationQueryTimeout() > 0) { + stmt.setQueryTimeout(getValidationQueryTimeout()); + } + rset = stmt.executeQuery(query); + if (!rset.next()) { + throw new SQLException("validationQuery didn't return a row"); + } + } finally { + if (rset != null) { + try { + rset.close(); + } catch (Exception t) { + // ignored + } + } + if (stmt != null) { + try { + stmt.close(); + } catch (Exception t) { + // ignored + } + } + } + } + } + + protected boolean testConnection(Connection conn) { + try { + String query = getValidationQuery(); + if (conn.isClosed()) { + return false; + } + if (null != query) { + Statement stmt = null; + ResultSet rset = null; + try { + stmt = conn.createStatement(); + if (getValidationQueryTimeout() > 0) { + stmt.setQueryTimeout(getValidationQueryTimeout()); + } + rset = stmt.executeQuery(query); + if (!rset.next()) { + return false; + } + } finally { + if (rset != null) { + try { + rset.close(); + } catch (Exception t) { + // ignored + } + } + if (stmt != null) { + try { + stmt.close(); + } catch (Exception t) { + // ignored + } + } + } + } + + return true; + } catch (SQLException ex) { + // skip + return false; + } + } + public long getCreateTimespanNano() { return createTimespan; } @@ -748,6 +829,8 @@ public abstract class DruidAbstractDataSource implements DataSource, DataSourceP if (dataSource.getDefaultCatalog() != null && dataSource.getDefaultCatalog().length() != 0) { conn.setCatalog(dataSource.getDefaultCatalog()); } + + dataSource.validateConnection(conn); } catch (SQLException ex) { dataSource.createErrorCount++; throw ex; diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 54c8fa17e1..25c0cee41f 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -17,7 +17,6 @@ package com.alibaba.druid.pool; import java.sql.Connection; import java.sql.Driver; -import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; @@ -181,30 +180,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat return this.activeConnections.keySet(); } - private boolean testConnection(Connection conn) { - String query = getValidationQuery(); - if (query == null || query.length() == 0) { - return true; - } - - Statement stmt = null; - ResultSet rs = null; - try { - stmt = conn.createStatement(); - rs = stmt.executeQuery(query); - if (rs.next()) { - return true; - } else { - return false; - } - } catch (SQLException e) { - return false; - } finally { - JdbcUtils.close(rs); - JdbcUtils.close(stmt); - } - } - @Override public Connection getConnection() throws SQLException { init(); diff --git a/src/test/java/com/alibaba/druid/bvt/pool/Case3_ValidateQuery.java b/src/test/java/com/alibaba/druid/bvt/pool/Case3_ValidateQuery.java new file mode 100644 index 0000000000..bca034a725 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/Case3_ValidateQuery.java @@ -0,0 +1,5 @@ +package com.alibaba.druid.bvt.pool; + +public class Case3_ValidateQuery { + +} diff --git a/src/test/java/com/alibaba/druid/pool/benckmark/Case1.java b/src/test/java/com/alibaba/druid/pool/benckmark/Case1.java index 6927bb2286..508bae1a6d 100644 --- a/src/test/java/com/alibaba/druid/pool/benckmark/Case1.java +++ b/src/test/java/com/alibaba/druid/pool/benckmark/Case1.java @@ -42,6 +42,7 @@ public class Case1 extends TestCase { private String validationQuery = "SELECT 1"; private int threadCount = 2; private int loopCount = 5; + final int LOOP_COUNT = 1000 * 1000; protected void setUp() throws Exception { jdbcUrl = "jdbc:fake:dragoon_v25masterdb"; @@ -64,7 +65,7 @@ public class Case1 extends TestCase { dataSource.setUsername(user); dataSource.setPassword(password); dataSource.setValidationQuery(validationQuery); - dataSource.setTestOnBorrow(true); + dataSource.setTestOnBorrow(false); for (int i = 0; i < loopCount; ++i) { p0(dataSource, "druid", threadCount); @@ -86,7 +87,7 @@ public class Case1 extends TestCase { dataSource.setUsername(user); dataSource.setPassword(password); dataSource.setValidationQuery("SELECT 1"); - dataSource.setTestOnBorrow(true); + dataSource.setTestOnBorrow(false); for (int i = 0; i < loopCount; ++i) { p0(dataSource, "dbcp", threadCount); @@ -111,7 +112,7 @@ public class Case1 extends TestCase { dataSource.setPartitionCount(1); dataSource.setAcquireIncrement(5); dataSource.setIdleConnectionTestPeriod(0L); - dataSource.setDisableConnectionTracking(true); + // dataSource.setDisableConnectionTracking(true); for (int i = 0; i < loopCount; ++i) { p0(dataSource, "boneCP", threadCount); @@ -129,8 +130,8 @@ public class Case1 extends TestCase { public void run() { try { startLatch.await(); - final int COUNT = 1000 * 1000; - for (int i = 0; i < COUNT; ++i) { + + for (int i = 0; i < LOOP_COUNT; ++i) { Connection conn = dataSource.getConnection(); conn.close(); }