From ff91ee541dcddf89998daa88c45c0ba0128c342a Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 8 Aug 2012 21:13:26 +0800 Subject: [PATCH] add DataSourceClosedException --- .../druid/pool/DataSourceClosedException.java | 21 ++++++++++ .../alibaba/druid/pool/DruidDataSource.java | 40 ++++++++++++------- .../alibaba/druid/bvt/pool/ClosedTest.java | 32 +++++++++++++++ 3 files changed, 78 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/pool/DataSourceClosedException.java create mode 100644 src/test/java/com/alibaba/druid/bvt/pool/ClosedTest.java diff --git a/src/main/java/com/alibaba/druid/pool/DataSourceClosedException.java b/src/main/java/com/alibaba/druid/pool/DataSourceClosedException.java new file mode 100644 index 0000000000..c003909874 --- /dev/null +++ b/src/main/java/com/alibaba/druid/pool/DataSourceClosedException.java @@ -0,0 +1,21 @@ +package com.alibaba.druid.pool; + +import java.sql.SQLException; + +public class DataSourceClosedException extends SQLException { + + private static final long serialVersionUID = 1L; + + public DataSourceClosedException(){ + super(); + } + + public DataSourceClosedException(String reason){ + super(reason); + } + + public DataSourceClosedException(Throwable cause){ + super(cause); + } + +} diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index f29afaa9af..b29009d5f2 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -72,7 +72,7 @@ import com.alibaba.druid.util.JdbcUtils; */ public class DruidDataSource extends DruidAbstractDataSource implements DruidDataSourceMBean, ManagedDataSource, Referenceable, Closeable, Cloneable, ConnectionPoolDataSource { - public final static Log LOG = LogFactory.getLog(DruidDataSource.class); + public final static Log LOG = LogFactory.getLog(DruidDataSource.class); private static final long serialVersionUID = 1L; @@ -117,6 +117,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat private String initStackTrace; private boolean closed = false; + private long closeTimeMillis = -1L; private JdbcDataSourceStat dataSourceStat; @@ -274,23 +275,23 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat if (this.driverClass != null) { this.driverClass = driverClass.trim(); } - + if (isTestOnBorrow() || isTestOnReturn() || isTestWhileIdle()) { if (this.getValidationQuery() == null || this.getValidationQuery().length() == 0) { String errorMessage = ""; - + if (isTestOnBorrow()) { errorMessage += "testOnBorrow is true, "; } - + if (isTestOnReturn()) { errorMessage += "testOnReturn is true, "; } - + if (isTestWhileIdle()) { errorMessage += "testWhileIdle is true, "; } - + LOG.error(errorMessage + "validationQuery not set"); } } @@ -301,9 +302,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat if (jdbcUrl.startsWith(DruidDriver.DEFAULT_PREFIX)) { DataSourceProxyConfig config = DruidDriver.parseConfig(jdbcUrl, null); this.driverClass = config.getRawDriverClassName(); - + LOG.error("error url : '" + jdbcUrl + "', it should be : '" + config.getRawUrl() + "'"); - + this.jdbcUrl = config.getRawUrl(); if (this.name == null) { this.name = config.getName(); @@ -366,7 +367,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } else if (realDriverClassName.equals("com.alibaba.druid.mock.MockDriver")) { this.exceptionSorter = new MockExceptionSorter(); } - + if (realDriverClassName.equals("com.mysql.jdbc.Driver")) { if (this.isPoolPreparedStatements()) { LOG.error("mysql should not use 'PoolPreparedStatements'"); @@ -554,6 +555,11 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } try { + if (closed) { + connectErrorCount.incrementAndGet(); + throw new DataSourceClosedException("dataSource already closed at " + new Date(closeTimeMillis)); + } + if (!enable) { connectErrorCount.incrementAndGet(); throw new DataSourceDisableException(); @@ -775,6 +781,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat notEmptySignalCount++; this.closed = true; + this.closeTimeMillis = System.currentTimeMillis(); for (Filter filter : filters) { filter.destory(); @@ -782,6 +789,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } finally { lock.unlock(); } + + LOG.warn("dataSource " + this.getID() + " closed"); } void incrementCreateCount() { @@ -879,7 +888,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat if (createError != null) { throw new GetConnectionTimeoutException(createError); } else { - throw new GetConnectionTimeoutException("loopWaitCount " + i + ", wait millis " + (nanos - estimate)/(1000 * 1000)); + throw new GetConnectionTimeoutException("loopWaitCount " + i + ", wait millis " + + (nanos - estimate) / (1000 * 1000)); } } } @@ -1105,11 +1115,11 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat for (; iter.hasNext();) { Map.Entry entry = iter.next(); DruidPooledConnection pooledConnection = entry.getKey(); - + if (pooledConnection.isRunning()) { continue; } - + ActiveConnectionTraceInfo activeInfo = entry.getValue(); long timeMillis = currentMillis - activeInfo.getConnectTime(); @@ -1447,15 +1457,15 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat PreparedStatementPool stmtPool = connHolder.getStatementPool(); for (PreparedStatementHolder stmtHolder : stmtPool.getMap().values()) { Map stmtInfo = new LinkedHashMap(); - + stmtInfo.put("sql", stmtHolder.getKey().getSql()); stmtInfo.put("defaultRowPretch", stmtHolder.getDefaultRowPretch()); stmtInfo.put("rowPrefetch", stmtHolder.getRowPrefetch()); stmtInfo.put("hitCount", stmtHolder.getHitCount()); - + stmtCache.add(stmtInfo); } - + map.put("pscache", stmtCache); } diff --git a/src/test/java/com/alibaba/druid/bvt/pool/ClosedTest.java b/src/test/java/com/alibaba/druid/bvt/pool/ClosedTest.java new file mode 100644 index 0000000000..7dd6f43385 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/ClosedTest.java @@ -0,0 +1,32 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.Connection; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DataSourceClosedException; +import com.alibaba.druid.pool.DruidDataSource; + +public class ClosedTest extends TestCase { + + public void test_close() throws Exception { + DruidDataSource dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + + Connection conn = dataSource.getConnection(); + conn.close(); + + dataSource.close(); + + DataSourceClosedException error = null; + + try { + dataSource.getConnection(); + } catch (DataSourceClosedException ex) { + error = ex; + } + + Assert.assertNotNull(error); + } +}