From 073838211723596133fa65bd448179d312ee709f Mon Sep 17 00:00:00 2001 From: wenshao Date: Mon, 7 Jul 2014 04:10:59 +0800 Subject: [PATCH] add notFullTimeoutRetryCount support --- .../druid/pool/DruidAbstractDataSource.java | 10 +++++ .../alibaba/druid/pool/DruidDataSource.java | 36 +++++++++++++++++- .../com/alibaba/druid/bvt/pool/FullTest.java | 37 +++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/pool/FullTest.java diff --git a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java index 80e1fa74ba..d746716083 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java @@ -118,6 +118,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements protected volatile int minIdle = DEFAULT_MIN_IDLE; protected volatile int maxIdle = DEFAULT_MAX_IDLE; protected volatile long maxWait = DEFAULT_MAX_WAIT; + protected int notFullTimeoutRetryCount = 0; protected volatile String validationQuery = DEFAULT_VALIDATION_QUERY; protected volatile int validationQueryTimeout = -1; @@ -892,6 +893,15 @@ public void setMaxWait(long maxWaitMillis) { this.maxWait = maxWaitMillis; } + + public int getNotFullTimeoutRetryCount() { + return notFullTimeoutRetryCount; + } + + + public void setNotFullTimeoutRetryCount(int notFullTimeoutRetryCount) { + this.notFullTimeoutRetryCount = notFullTimeoutRetryCount; + } public int getMinIdle() { return minIdle; diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 07726af918..f21df11059 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -238,6 +238,17 @@ public void configFromPropety(Properties properties) { this.setResetStatEnable(value); } } + { + String property = properties.getProperty("druid.notFullTimeoutRetryCount"); + if (property != null && property.length() > 0) { + try { + int value = Integer.parseInt(property); + this.setNotFullTimeoutRetryCount(value); + } catch (NumberFormatException e) { + LOG.error("illegal property 'druid.notFullTimeoutRetryCount'", e); + } + } + } } public boolean isUseGlobalDataSourceStat() { @@ -897,8 +908,22 @@ public PooledConnection getPooledConnection(String user, String password) throws } public DruidPooledConnection getConnectionDirect(long maxWaitMillis) throws SQLException { + int notFullTimeoutRetryCnt = 0; for (;;) { - DruidPooledConnection poolableConnection = getConnectionInternal(maxWaitMillis); + // handle notFullTimeoutRetry + DruidPooledConnection poolableConnection; + try { + poolableConnection = getConnectionInternal(maxWaitMillis); + } catch (GetConnectionTimeoutException ex) { + if (notFullTimeoutRetryCnt <= this.notFullTimeoutRetryCount && !isFull()) { + notFullTimeoutRetryCnt++; + if (LOG.isWarnEnabled()) { + LOG.warn("not full timeout retry : " + notFullTimeoutRetryCnt); + } + continue; + } + throw ex; + } if (isTestOnBorrow()) { boolean validate = testConnectionInternal(poolableConnection.getConnection()); @@ -2497,4 +2522,13 @@ private boolean isFillable(int toCount) { return true; } } + + public boolean isFull() { + lock.lock(); + try { + return this.poolingCount + this.activeCount >= this.maxActive; + } finally { + lock.unlock(); + } + } } diff --git a/src/test/java/com/alibaba/druid/bvt/pool/FullTest.java b/src/test/java/com/alibaba/druid/bvt/pool/FullTest.java new file mode 100644 index 0000000000..7a66d6027c --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/FullTest.java @@ -0,0 +1,37 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.Connection; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DruidDataSource; + +public class FullTest extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setTestOnBorrow(false); + + dataSource.init(); + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void test_restart() throws Exception { + Assert.assertEquals(false, dataSource.isFull()); + dataSource.fill(); + + Assert.assertEquals(true, dataSource.isFull()); + Connection conn = dataSource.getConnection(); + Assert.assertEquals(true, dataSource.isFull()); + conn.close(); + Assert.assertEquals(true, dataSource.isFull()); + } +}