diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 7848729ce4..22295429ad 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -512,6 +512,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat // exceptionSorter.isExceptionFatal if (exceptionSorter != null && exceptionSorter.isExceptionFatal(sqlEx)) { + if (pooledConnection.isTraceEnable()) { + activeConnections.remove(pooledConnection); + } this.discardConnection(holder.getConnection()); pooledConnection.disable(); } diff --git a/src/main/java/com/alibaba/druid/pool/PoolableConnection.java b/src/main/java/com/alibaba/druid/pool/PoolableConnection.java index 1de3cb8f5a..62292ec754 100644 --- a/src/main/java/com/alibaba/druid/pool/PoolableConnection.java +++ b/src/main/java/com/alibaba/druid/pool/PoolableConnection.java @@ -58,6 +58,7 @@ public class PoolableConnection implements PooledConnection, Connection { protected TransactionInfo transactionInfo; private final boolean dupCloseLogEnable; private boolean traceEnable = false; + private boolean diable = false; public PoolableConnection(ConnectionHolder holder){ this.conn = holder.getConnection(); @@ -126,14 +127,24 @@ public class PoolableConnection implements PooledConnection, Connection { } void disable() { + this.traceEnable = false; this.holder = null; this.transactionInfo = null; + this.diable = true; + } + + public boolean isDiable() { + return diable; } @Override public void close() throws SQLException { ConnectionHolder holder = this.holder; + if (this.diable) { + return; + } + if (holder == null && dupCloseLogEnable) { LOG.error("dup close"); return; diff --git a/src/test/java/com/alibaba/druid/bvt/pool/Bug_for_dupCloseStmtError.java b/src/test/java/com/alibaba/druid/bvt/pool/Bug_for_dupCloseStmtError.java index 139938ef7e..2042830508 100644 --- a/src/test/java/com/alibaba/druid/bvt/pool/Bug_for_dupCloseStmtError.java +++ b/src/test/java/com/alibaba/druid/bvt/pool/Bug_for_dupCloseStmtError.java @@ -3,9 +3,12 @@ package com.alibaba.druid.bvt.pool; import java.sql.Connection; import java.sql.PreparedStatement; +import org.junit.Assert; + import junit.framework.TestCase; import com.alibaba.druid.mock.MockConnection; +import com.alibaba.druid.mock.MockConnectionClosedException; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.stat.DruidDataSourceStatManager; @@ -17,6 +20,7 @@ public class Bug_for_dupCloseStmtError extends TestCase { dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:mock:"); dataSource.setPoolPreparedStatements(false); + dataSource.setTestOnBorrow(true); } protected void tearDown() throws Exception { @@ -26,14 +30,24 @@ public class Bug_for_dupCloseStmtError extends TestCase { } } - public void test_0() throws Exception { + public void test_2() throws Exception { { Connection conn = dataSource.getConnection(); PreparedStatement stmt = conn.prepareStatement("select 1"); stmt.setString(1, "xx"); - + MockConnection mockConn = conn.unwrap(MockConnection.class); mockConn.close(); + + MockConnectionClosedException error = null; + try { + stmt.execute(); + } catch (MockConnectionClosedException ex) { + error = ex; + } + + Assert.assertNotNull(error); + conn.close(); stmt.close(); } @@ -43,5 +57,6 @@ public class Bug_for_dupCloseStmtError extends TestCase { stmt.close(); conn.close(); } + Assert.assertEquals(0, dataSource.getDupCloseCount()); } }