diff --git a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java index c7abf46c2d..71df20bac6 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java @@ -55,6 +55,7 @@ public abstract class DruidAbstractDataSource implements DataSource, DataSourceP public final static boolean DEFAULT_TEST_ON_RETURN = false; public final static boolean DEFAULT_WHILE_IDLE = false; public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L; + public static final long DEFAULT_TIME_BETWEEN_CONNECT_ERROR_MILLIS = 30 * 1000; public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 1; /** @@ -132,6 +133,8 @@ public abstract class DruidAbstractDataSource implements DataSource, DataSourceP protected String dbType; + protected long timeBetweenConnectErrorMillis = DEFAULT_TIME_BETWEEN_CONNECT_ERROR_MILLIS; + public String getDbType() { return dbType; } @@ -173,6 +176,14 @@ public abstract class DruidAbstractDataSource implements DataSource, DataSourceP } } + public long getTimeBetweenConnectErrorMillis() { + return timeBetweenConnectErrorMillis; + } + + public void setTimeBetweenConnectErrorMillis(long timeBetweenConnectErrorMillis) { + this.timeBetweenConnectErrorMillis = timeBetweenConnectErrorMillis; + } + public int getMaxOpenPreparedStatements() { return maxOpenPreparedStatements; } @@ -594,7 +605,7 @@ public abstract class DruidAbstractDataSource implements DataSource, DataSourceP public Driver getDriver() { return driver; } - + public void setDriver(Driver driver) { this.driver = driver; } @@ -719,7 +730,7 @@ public abstract class DruidAbstractDataSource implements DataSource, DataSourceP conn = new FilterChainImpl(dataSource).connection_connect(info); } else { conn = dataSource.getDriver().connect(url, info); - + if (conn == null) { throw new SQLException("connect error, url " + url); } diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 6644cebee6..54c8fa17e1 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -536,6 +536,19 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat break; } catch (SQLException e) { printStackTrace(e); + + if (timeBetweenConnectErrorMillis > 0) { + try { + Thread.sleep(timeBetweenConnectErrorMillis); + } catch (InterruptedException e1) { + break; + } + } + } catch (RuntimeException e) { + printStackTrace(e); + } catch (Error e) { + printStackTrace(e); + break; } finally { lock.unlock(); } diff --git a/src/test/java/com/alibaba/druid/bvt/pool/Case1.java b/src/test/java/com/alibaba/druid/bvt/pool/Case1.java new file mode 100644 index 0000000000..39bd4fe547 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/Case1.java @@ -0,0 +1,40 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Properties; + +import com.alibaba.druid.mock.MockDriver; +import com.alibaba.druid.pool.DruidDataSource; + +import junit.framework.TestCase; + +public class Case1 extends TestCase { + + public void test_f() throws Exception { + final DruidDataSource dataSource = new DruidDataSource(); + dataSource.setTimeBetweenConnectErrorMillis(100); + + final long startTime = System.currentTimeMillis(); + final long okTime = startTime + 1000 * 1; + + dataSource.setDriver(new MockDriver() { + @Override + public Connection connect(String url, Properties info) throws SQLException { + if (System.currentTimeMillis() < okTime) { + throw new SQLException(); + } + + return super.connect(url, info); + } + }); + dataSource.setUrl("jdbc:mock:"); + + dataSource.setMinIdle(0); + dataSource.setMaxActive(2); + dataSource.setMaxIdle(2); + + Connection conn = dataSource.getConnection(); + conn.close(); + } +}