diff --git a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java index c2c4cf47bf..ad1f032472 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java @@ -143,7 +143,7 @@ public abstract class DruidAbstractDataSource implements DruidAbstractDataSource protected boolean removeAbandoned; - protected int removeAbandonedTimeout; + protected int removeAbandonedTimeoutMillis; protected boolean logAbandoned; @@ -263,11 +263,15 @@ public abstract class DruidAbstractDataSource implements DruidAbstractDataSource } public int getRemoveAbandonedTimeout() { - return removeAbandonedTimeout; + return removeAbandonedTimeoutMillis / 1000; } public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) { - this.removeAbandonedTimeout = removeAbandonedTimeout; + this.removeAbandonedTimeoutMillis = removeAbandonedTimeout * 1000; + } + + public void setRemoveAbandonedTimeoutMillis(int removeAbandonedTimeoutMillis) { + this.removeAbandonedTimeoutMillis = removeAbandonedTimeoutMillis; } public boolean isRemoveAbandoned() { diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 15d561aee4..e86c751d27 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -21,7 +21,9 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -88,7 +90,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat public DruidDataSource(){ } - + public void resetStat() { lock.lock(); try { @@ -313,6 +315,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat /** * 抛弃连接,不进行回收,而是抛弃 + * * @param realConnection * @throws SQLException */ @@ -412,6 +415,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat assert holder != null; + if (isRemoveAbandoned()) { + activeConnections.remove(pooledConnection); + } + try { // 第一步,检查连接是否关闭 if (conn == null || conn.isClosed()) { @@ -747,12 +754,26 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat break; } - if (poolingCount <= 0) { - Thread.sleep(minEvictableIdleTimeMillis); - continue; - } - shrink(true); + + if (isRemoveAbandoned()) { + Iterator> iter = activeConnections.entrySet().iterator(); + + long currentMillis = 0; + for (; iter.hasNext();) { + if (currentMillis == 0) { + System.currentTimeMillis(); + } + Map.Entry entry = iter.next(); + ActiveConnectionTraceInfo activeInfo = entry.getValue(); + long timeMillis = activeInfo.getConnectTime() - currentMillis; + + if (timeMillis >= removeAbandonedTimeoutMillis) { + PoolableConnection pooledConnection = entry.getKey(); + JdbcUtils.close(pooledConnection); + } + } + } } catch (InterruptedException e) { break; } diff --git a/src/test/java/com/alibaba/druid/bvt/pool/TestAbondon.java b/src/test/java/com/alibaba/druid/bvt/pool/TestAbondon.java new file mode 100644 index 0000000000..9dedf3d326 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/TestAbondon.java @@ -0,0 +1,35 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.Connection; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.stat.DruidDataSourceStatManager; + +public class TestAbondon extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setRemoveAbandoned(true); + dataSource.setRemoveAbandonedTimeoutMillis(10); + dataSource.setTimeBetweenEvictionRunsMillis(1); + dataSource.setUrl("jdbc:mock:xxx"); + + } + + protected void tearDown() throws Exception { + dataSource.close(); + Assert.assertEquals(0, DruidDataSourceStatManager.getInstance().getDataSourceList().size()); + } + + public void test_0() throws Exception { + Connection conn = dataSource.getConnection(); + Assert.assertEquals(false, conn.isClosed()); + Thread.sleep(100); + Assert.assertEquals(true, conn.isClosed()); + } +}