diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 2f7d267789..d83f8e8b9a 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -1075,11 +1075,16 @@ 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(); if (timeMillis >= removeAbandonedTimeoutMillis) { - DruidPooledConnection pooledConnection = entry.getKey(); JdbcUtils.close(pooledConnection); removeAbandonedCount++; removeCount++; diff --git a/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java b/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java index 2234852aa4..cb29229046 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java +++ b/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java @@ -54,18 +54,19 @@ import com.alibaba.druid.support.logging.LogFactory; */ public class DruidPooledConnection implements javax.sql.PooledConnection, Connection { - private final static Log LOG = LogFactory.getLog(DruidPooledConnection.class); + private final static Log LOG = LogFactory.getLog(DruidPooledConnection.class); - protected Connection conn; - protected ConnectionHolder holder; - protected TransactionInfo transactionInfo; - private final boolean dupCloseLogEnable; - private boolean traceEnable = false; - private boolean diable = false; - private boolean closed = false; - private final Thread ownerThread; + protected Connection conn; + protected ConnectionHolder holder; + protected TransactionInfo transactionInfo; + private final boolean dupCloseLogEnable; + private boolean traceEnable = false; + private boolean diable = false; + private boolean closed = false; + private final Thread ownerThread; - private long connectedTimeNano; + private long connectedTimeNano; + private volatile boolean running = false; public DruidPooledConnection(ConnectionHolder holder){ this.conn = holder.getConnection(); @@ -180,7 +181,7 @@ public class DruidPooledConnection implements javax.sql.PooledConnection, Connec } return; } - + for (ConnectionEventListener listener : holder.getConnectionEventListeners()) { listener.connectionClosed(new ConnectionEvent(this)); } @@ -1003,4 +1004,17 @@ public class DruidPooledConnection implements javax.sql.PooledConnection, Connec public int getNetworkTimeout() throws SQLException { throw new SQLFeatureNotSupportedException(); } + + final void beforeExecute() { + running = true; + } + + final void afterExecute() { + running = false; + } + + public boolean isRunning() { + return running; + } + } diff --git a/src/main/java/com/alibaba/druid/pool/DruidPooledPreparedStatement.java b/src/main/java/com/alibaba/druid/pool/DruidPooledPreparedStatement.java index 25be6d6dbb..082765acb0 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidPooledPreparedStatement.java +++ b/src/main/java/com/alibaba/druid/pool/DruidPooledPreparedStatement.java @@ -177,6 +177,7 @@ public class DruidPooledPreparedStatement extends DruidPooledStatement implement oracleSetRowPrefetch(); + conn.beforeExecute(); try { ResultSet rs = stmt.executeQuery(); @@ -186,6 +187,8 @@ public class DruidPooledPreparedStatement extends DruidPooledStatement implement return poolableResultSet; } catch (Throwable t) { throw checkException(t); + } finally { + conn.afterExecute(); } } @@ -196,10 +199,13 @@ public class DruidPooledPreparedStatement extends DruidPooledStatement implement incrementExecuteCount(); transactionRecord(sql); + conn.beforeExecute(); try { return stmt.executeUpdate(); } catch (Throwable t) { throw checkException(t); + } finally { + conn.afterExecute(); } } @@ -433,10 +439,13 @@ public class DruidPooledPreparedStatement extends DruidPooledStatement implement // oracleSetRowPrefetch(); + conn.beforeExecute(); try { return stmt.execute(); } catch (Throwable t) { throw checkException(t); + } finally { + conn.afterExecute(); } } @@ -494,10 +503,13 @@ public class DruidPooledPreparedStatement extends DruidPooledStatement implement incrementExecuteCount(); transactionRecord(sql); + conn.beforeExecute(); try { return super.executeBatch(); } catch (Throwable t) { throw checkException(t); + } finally { + conn.afterExecute(); } } diff --git a/src/main/java/com/alibaba/druid/pool/DruidPooledStatement.java b/src/main/java/com/alibaba/druid/pool/DruidPooledStatement.java index 4ae4a365f0..629d8bf274 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidPooledStatement.java +++ b/src/main/java/com/alibaba/druid/pool/DruidPooledStatement.java @@ -35,7 +35,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement { private final static Log LOG = LogFactory.getLog(DruidPooledStatement.class); private final Statement stmt; - protected DruidPooledConnection conn; + protected DruidPooledConnection conn; protected final List resultSetTrace = new ArrayList(); protected boolean closed = false; protected int fetchRowPeak = -1; @@ -96,6 +96,10 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement { this.getPoolableConnection().getConnectionHolder().getDataSource().incrementExecuteCount(); } + protected void transactionRecord(String sql) throws SQLException { + conn.transactionRecord(sql); + } + @Override public final ResultSet executeQuery(String sql) throws SQLException { checkOpen(); @@ -103,6 +107,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement { incrementExecuteCount(); transactionRecord(sql); + conn.beforeExecute(); try { ResultSet rs = stmt.executeQuery(sql); @@ -112,13 +117,11 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement { return poolableResultSet; } catch (Throwable t) { throw checkException(t); + } finally { + conn.afterExecute(); } } - protected void transactionRecord(String sql) throws SQLException { - conn.transactionRecord(sql); - } - @Override public final int executeUpdate(String sql) throws SQLException { checkOpen(); @@ -126,20 +129,115 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement { incrementExecuteCount(); transactionRecord(sql); + conn.beforeExecute(); try { return stmt.executeUpdate(sql); } catch (Throwable t) { throw checkException(t); + } finally { + conn.afterExecute(); } } @Override - public void close() throws SQLException { - if (!this.closed) { - clearResultSet(); - stmt.close(); - this.closed = true; - conn.getConnectionHolder().removeTrace(this); + public final int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + checkOpen(); + + incrementExecuteCount(); + transactionRecord(sql); + + conn.beforeExecute(); + try { + return stmt.executeUpdate(sql, autoGeneratedKeys); + } catch (Throwable t) { + throw checkException(t); + } finally { + conn.afterExecute(); + } + } + + @Override + public final int executeUpdate(String sql, int columnIndexes[]) throws SQLException { + checkOpen(); + + incrementExecuteCount(); + transactionRecord(sql); + + conn.beforeExecute(); + try { + return stmt.executeUpdate(sql, columnIndexes); + } catch (Throwable t) { + throw checkException(t); + } finally { + conn.afterExecute(); + } + } + + @Override + public final int executeUpdate(String sql, String columnNames[]) throws SQLException { + checkOpen(); + + incrementExecuteCount(); + transactionRecord(sql); + + conn.beforeExecute(); + try { + return stmt.executeUpdate(sql, columnNames); + } catch (Throwable t) { + throw checkException(t); + } finally { + conn.afterExecute(); + } + } + + @Override + public final boolean execute(String sql, int autoGeneratedKeys) throws SQLException { + checkOpen(); + + incrementExecuteCount(); + transactionRecord(sql); + + conn.beforeExecute(); + try { + return stmt.execute(sql, autoGeneratedKeys); + } catch (Throwable t) { + throw checkException(t); + } finally { + conn.afterExecute(); + } + } + + @Override + public final boolean execute(String sql, int columnIndexes[]) throws SQLException { + checkOpen(); + + incrementExecuteCount(); + transactionRecord(sql); + + conn.beforeExecute(); + try { + return stmt.execute(sql, columnIndexes); + } catch (Throwable t) { + throw checkException(t); + } finally { + conn.afterExecute(); + } + } + + @Override + public final boolean execute(String sql, String columnNames[]) throws SQLException { + checkOpen(); + + incrementExecuteCount(); + transactionRecord(sql); + + conn.beforeExecute(); + try { + return stmt.execute(sql, columnNames); + } catch (Throwable t) { + throw checkException(t); + } finally { + conn.afterExecute(); } } @@ -153,6 +251,16 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement { throw checkException(t); } } + + @Override + public void close() throws SQLException { + if (!this.closed) { + clearResultSet(); + stmt.close(); + this.closed = true; + conn.getConnectionHolder().removeTrace(this); + } + } @Override public void setMaxFieldSize(int max) throws SQLException { @@ -415,10 +523,13 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement { incrementExecuteCount(); + conn.beforeExecute(); try { return stmt.executeBatch(); } catch (Throwable t) { throw checkException(t); + } finally { + conn.afterExecute(); } } @@ -457,90 +568,6 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement { } } - @Override - public final int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { - checkOpen(); - - incrementExecuteCount(); - transactionRecord(sql); - - try { - return stmt.executeUpdate(sql, autoGeneratedKeys); - } catch (Throwable t) { - throw checkException(t); - } - } - - @Override - public final int executeUpdate(String sql, int columnIndexes[]) throws SQLException { - checkOpen(); - - incrementExecuteCount(); - transactionRecord(sql); - - try { - return stmt.executeUpdate(sql, columnIndexes); - } catch (Throwable t) { - throw checkException(t); - } - } - - @Override - public final int executeUpdate(String sql, String columnNames[]) throws SQLException { - checkOpen(); - - incrementExecuteCount(); - transactionRecord(sql); - - try { - return stmt.executeUpdate(sql, columnNames); - } catch (Throwable t) { - throw checkException(t); - } - } - - @Override - public final boolean execute(String sql, int autoGeneratedKeys) throws SQLException { - checkOpen(); - - incrementExecuteCount(); - transactionRecord(sql); - - try { - return stmt.execute(sql, autoGeneratedKeys); - } catch (Throwable t) { - throw checkException(t); - } - } - - @Override - public final boolean execute(String sql, int columnIndexes[]) throws SQLException { - checkOpen(); - - incrementExecuteCount(); - transactionRecord(sql); - - try { - return stmt.execute(sql, columnIndexes); - } catch (Throwable t) { - throw checkException(t); - } - } - - @Override - public final boolean execute(String sql, String columnNames[]) throws SQLException { - checkOpen(); - - incrementExecuteCount(); - transactionRecord(sql); - - try { - return stmt.execute(sql, columnNames); - } catch (Throwable t) { - throw checkException(t); - } - } - @Override public final int getResultSetHoldability() throws SQLException { checkOpen(); @@ -582,7 +609,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement { public boolean isCloseOnCompletion() throws SQLException { return false; } - + @SuppressWarnings("unchecked") public T unwrap(Class iface) throws SQLException { if (iface == Statement.class) { @@ -591,7 +618,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement { } return (T) stmt; } - + return super.unwrap(iface); } }