diff --git a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java index 177f5164e7..4905185534 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java @@ -868,11 +868,7 @@ public abstract class DruidAbstractDataSource implements DruidAbstractDataSource } } - protected void handleException(Throwable e) throws SQLException { - errorCount.incrementAndGet(); - } - - abstract void decrementActiveCountWithLock(); + public abstract void handleConnectionException(PoolableConnection pooledConnection, Throwable t) throws SQLException; protected abstract void recycle(PoolableConnection pooledConnection) throws SQLException; diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index e2907fba22..904e722e91 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -33,6 +33,8 @@ import javax.naming.NamingException; import javax.naming.Reference; import javax.naming.Referenceable; import javax.naming.StringRefAddr; +import javax.sql.ConnectionEvent; +import javax.sql.ConnectionEventListener; import com.alibaba.druid.filter.Filter; import com.alibaba.druid.logging.Log; @@ -331,6 +333,33 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } return poolalbeConnection; } + + public void handleConnectionException(PoolableConnection pooledConnection, Throwable t) throws SQLException { + final ConnectionHolder holder = pooledConnection.getConnectionHolder(); + + errorCount.incrementAndGet(); + + if (t instanceof SQLException) { + SQLException sqlEx = (SQLException) t; + + // broadcastConnectionError + ConnectionEvent event = new ConnectionEvent(pooledConnection, sqlEx); + for (ConnectionEventListener eventListener : holder.getConnectionEventListeners()) { + eventListener.connectionErrorOccurred(event); + } + + // exceptionSorter.isExceptionFatal + if (exceptionSoter != null && exceptionSoter.isExceptionFatal(sqlEx)) { + decrementActiveCountWithLock(); + JdbcUtils.close(holder.getConnection()); + pooledConnection.disable(); + } + + throw sqlEx; + } else { + throw new SQLException("Error", t); + } + } /** * 回收连接 diff --git a/src/main/java/com/alibaba/druid/pool/PoolableConnection.java b/src/main/java/com/alibaba/druid/pool/PoolableConnection.java index 0b37bf8229..56c28938ef 100644 --- a/src/main/java/com/alibaba/druid/pool/PoolableConnection.java +++ b/src/main/java/com/alibaba/druid/pool/PoolableConnection.java @@ -66,38 +66,15 @@ public class PoolableConnection implements PooledConnection, Connection { if (holder != null) { DruidAbstractDataSource dataSource = holder.getDataSource(); if (dataSource != null) { - holder.getDataSource().handleException(t); + holder.getDataSource().handleConnectionException(this, t); } } - + if (t instanceof SQLException) { - SQLException sqlEx = (SQLException) t; - - // broadcastConnectionError - ConnectionEvent event = new ConnectionEvent(this, sqlEx); - for (ConnectionEventListener eventListener : holder.getConnectionEventListeners()) { - eventListener.connectionErrorOccurred(event); - } - - // exceptionSorter.isExceptionFatal - if (holder != null) { - DruidAbstractDataSource dataSource = holder.getDataSource(); - - if (dataSource != null) { - ExceptionSorter exceptionSorter = dataSource.getExceptionSoter(); - if (exceptionSorter != null && exceptionSorter.isExceptionFatal(sqlEx)) { - if (holder != null) { - dataSource.decrementActiveCountWithLock(); - this.holder = null; // isClosed() is true - } - } - } - } - - throw sqlEx; - } else { - throw new SQLException("Error", t); + throw (SQLException) t; } + + throw new SQLException("Error", t); } void closePoolableStatement(PoolablePreparedStatement stmt) throws SQLException { @@ -123,6 +100,10 @@ public class PoolableConnection implements PooledConnection, Connection { public Connection getConnection() { return conn; } + + void disable() { + this.holder = null; + } @Override public void close() throws SQLException {