diff --git a/src/main/java/com/alibaba/druid/pool/ConnectionHolder.java b/src/main/java/com/alibaba/druid/pool/ConnectionHolder.java index c4a5444059..42320e32bc 100644 --- a/src/main/java/com/alibaba/druid/pool/ConnectionHolder.java +++ b/src/main/java/com/alibaba/druid/pool/ConnectionHolder.java @@ -16,6 +16,7 @@ package com.alibaba.druid.pool; import java.sql.Connection; +import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Date; @@ -40,16 +41,24 @@ public final class ConnectionHolder { private long lastActiveTimeMillis; private long useCount = 0; - private PreparedStatementPool statementPool; + private PreparedStatementPool statementPool; private final List statementTrace = new ArrayList(); - public ConnectionHolder(DruidAbstractDataSource dataSource, Connection conn){ + private boolean defaultReadOnly; + private int defaultHoldability; + private int defaultTransactionIsolation; + + public ConnectionHolder(DruidAbstractDataSource dataSource, Connection conn) throws SQLException{ this.dataSource = dataSource; this.conn = conn; this.connecttimeMillis = System.currentTimeMillis(); this.lastActiveTimeMillis = connecttimeMillis; + this.defaultReadOnly = conn.isReadOnly(); + this.defaultHoldability = conn.getHoldability(); + this.defaultTransactionIsolation = conn.getTransactionIsolation(); + statementPool = null; } @@ -108,7 +117,11 @@ public final class ConnectionHolder { useCount++; } - public void reset() { + public void reset() throws SQLException { + conn.setReadOnly(defaultReadOnly); + conn.setHoldability(defaultHoldability); + conn.setTransactionIsolation(defaultTransactionIsolation); + connectionEventListeners.clear(); statementEventListeners.clear(); @@ -118,7 +131,7 @@ public final class ConnectionHolder { } statementTrace.clear(); } - + public String toString() { StringBuilder buf = new StringBuilder(); @@ -126,24 +139,24 @@ public final class ConnectionHolder { buf.append(System.identityHashCode(conn)); buf.append(", ConnectTime:\""); buf.append(JdbcUtils.toString(new Date(this.connecttimeMillis))); - + buf.append("\", UseCount:"); buf.append(useCount); - + if (lastActiveTimeMillis > 0) { buf.append(", LastActiveTime:\""); buf.append(JdbcUtils.toString(new Date(this.lastActiveTimeMillis))); buf.append("\""); } - + PreparedStatementPool statmentPool = this.getStatementPool(); if (statmentPool != null && statmentPool.getMap().size() > 0) { buf.append("\", CachedStatementCount:"); buf.append(this.getStatementPool().getMap().size()); } - + buf.append("}"); - + return buf.toString(); } diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 7d4a8be279..0f953113f0 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -865,6 +865,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat notEmpty.signal(); notEmptySignalCount++; + } catch (SQLException ex) { + LOG.error("create connection holder error", ex); + break; } finally { lock.unlock(); } diff --git a/src/main/java/com/alibaba/druid/pool/PoolableConnection.java b/src/main/java/com/alibaba/druid/pool/PoolableConnection.java index 346274c57a..3461b1855d 100644 --- a/src/main/java/com/alibaba/druid/pool/PoolableConnection.java +++ b/src/main/java/com/alibaba/druid/pool/PoolableConnection.java @@ -57,7 +57,7 @@ public class PoolableConnection implements PooledConnection, Connection { protected ConnectionHolder holder; protected TransactionInfo transactionInfo; - public PoolableConnection(ConnectionHolder holder){ + public PoolableConnection(ConnectionHolder holder) { this.conn = holder.getConnection(); this.holder = holder; } @@ -188,7 +188,7 @@ public class PoolableConnection implements PooledConnection, Connection { if (stmtHolder == null) { try { stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, resultSetType, - resultSetConcurrency)); + resultSetConcurrency)); holder.getDataSource().incrementPreparedStatementCount(); holder.getStatementPool().put(stmtHolder); } catch (SQLException ex) { @@ -389,8 +389,8 @@ public class PoolableConnection implements PooledConnection, Connection { if (stmtHolder == null) { try { stmtHolder = new PreparedStatementHolder(key, conn.prepareCall(sql, resultSetType, - resultSetConcurrency, - resultSetHoldability)); + resultSetConcurrency, + resultSetHoldability)); holder.getDataSource().incrementPreparedStatementCount(); holder.getStatementPool().put(stmtHolder); } catch (SQLException ex) { @@ -422,8 +422,8 @@ public class PoolableConnection implements PooledConnection, Connection { if (stmtHolder == null) { try { - stmtHolder = new PreparedStatementHolder(key, conn.prepareCall(sql, resultSetType, - resultSetConcurrency)); + stmtHolder = new PreparedStatementHolder(key, + conn.prepareCall(sql, resultSetType, resultSetConcurrency)); holder.getDataSource().incrementPreparedStatementCount(); holder.getStatementPool().put(stmtHolder); } catch (SQLException ex) { diff --git a/src/test/java/com/alibaba/druid/bvt/pool/TestDefault.java b/src/test/java/com/alibaba/druid/bvt/pool/TestDefault.java new file mode 100644 index 0000000000..3ae3e76e7f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/TestDefault.java @@ -0,0 +1,61 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.stat.DruidDataSourceStatManager; + +public class TestDefault extends TestCase { + + protected void setUp() throws Exception { + Assert.assertEquals(0, DruidDataSourceStatManager.getInstance().getDataSourceList().size()); + } + + protected void tearDown() throws Exception { + Assert.assertEquals(0, DruidDataSourceStatManager.getInstance().getDataSourceList().size()); + } + + public void test_close() throws Exception { + DruidDataSource dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + + String sql = "SELECT 1"; + { + Connection conn = dataSource.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql); + ResultSet rs = stmt.executeQuery(); + rs.next(); + + Assert.assertEquals(0, conn.getHoldability()); + Assert.assertEquals(false, conn.isReadOnly()); + Assert.assertEquals(0, conn.getTransactionIsolation()); + + conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT); + conn.setReadOnly(false); + conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); + + conn.close(); + + Assert.assertEquals(true, stmt.isClosed()); + Assert.assertEquals(true, rs.isClosed()); + + rs.close(); + stmt.close(); + } + + Connection conn = dataSource.getConnection(); + + Assert.assertEquals(0, conn.getHoldability()); + Assert.assertEquals(false, conn.isReadOnly()); + Assert.assertEquals(0, conn.getTransactionIsolation()); + + conn.close(); + + dataSource.close(); + } +}