diff --git a/src/main/java/com/alibaba/druid/filter/stat/TransactionInfo.java b/src/main/java/com/alibaba/druid/filter/stat/TransactionInfo.java new file mode 100644 index 0000000000..7e5fdf8de9 --- /dev/null +++ b/src/main/java/com/alibaba/druid/filter/stat/TransactionInfo.java @@ -0,0 +1,38 @@ +package com.alibaba.druid.filter.stat; + +import java.util.ArrayList; +import java.util.List; + +public class TransactionInfo { + + private final long id; + private final List sqlList = new ArrayList(); + private final long startTimeMillis; + private long endTimeMillis; + + public TransactionInfo(long id){ + this.id = id; + this.startTimeMillis = System.currentTimeMillis(); + } + + public long getId() { + return id; + } + + public List getSqlList() { + return sqlList; + } + + public long getStartTimeMillis() { + return startTimeMillis; + } + + public long getEndTimeMillis() { + return endTimeMillis; + } + + public void setEndTimeMillis(long endTimeMillis) { + this.endTimeMillis = endTimeMillis; + } + +} diff --git a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java index e248e187c8..c749177ab6 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java @@ -683,12 +683,12 @@ public abstract class DruidAbstractDataSource implements DruidAbstractDataSource } public void setProxyFilters(List filters) { - this.filters = filters; + if (filters != null) { + this.filters.addAll(filters); + } } public void setFilters(String filters) throws SQLException { - this.filters.clear(); - if (filters == null || filters.length() == 0) { return; } @@ -820,6 +820,7 @@ public abstract class DruidAbstractDataSource implements DruidAbstractDataSource private final AtomicLong connectionIdSeed = new AtomicLong(10000); private final AtomicLong statementIdSeed = new AtomicLong(20000); private final AtomicLong resultSetIdSeed = new AtomicLong(50000); + private final AtomicLong transactionIdSeed = new AtomicLong(50000); public long createConnectionId() { return connectionIdSeed.incrementAndGet(); @@ -832,6 +833,11 @@ public abstract class DruidAbstractDataSource implements DruidAbstractDataSource public long createResultSetId() { return resultSetIdSeed.getAndIncrement(); } + + @Override + public long createTransactionId() { + return transactionIdSeed.getAndIncrement(); + } void initStatement(Statement stmt) throws SQLException { if (queryTimeout > 0) { diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 4df29a73f6..076c677ba8 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -275,6 +275,22 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat JdbcUtils.close(realConnection); continue; } + + if (isTestWhileIdle()) { + long idleMillis = System.currentTimeMillis() - poolalbeConnection.getConnectionHolder().getLastActiveTimeMillis(); + if (idleMillis >= this.getTimeBetweenEvictionRunsMillis()) { + boolean validate = testConnectionInternal(poolalbeConnection.getConnection()); + if (!validate) { + if (LOG.isDebugEnabled()) { + LOG.debug("skip not validate connection."); + } + + JdbcUtils.close(realConnection); + continue; + } + poolalbeConnection.getConnectionHolder().setLastCheckTimeMillis(System.currentTimeMillis()); + } + } } if (isRemoveAbandoned()) { @@ -679,7 +695,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat final List evictList = new ArrayList(); final List idleList = new ArrayList(); - List checkList = new ArrayList(); FOR_0: for (;;) { // 从前面开始删除 try { @@ -740,40 +755,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat for (ConnectionHolder idleConnection : idleList) { if (!testConnectionInternal(idleConnection.getConnection())) { evictList.add(idleConnection); - } else { - idleConnection.setLastCheckTimeMillis(System.currentTimeMillis()); - checkList.add(idleConnection); } } - int size = checkList.size(); - if (size > 0) { - lock.lock(); - try { - for (int i = 0; i < size; ++i) { - ConnectionHolder connection = checkList.get(i); - connections[count++] = connection; - } - } finally { - lock.unlock(); - } - if (LOG.isDebugEnabled()) { - StringBuilder buf = new StringBuilder(); - buf.append("checked "); - buf.append(size); - buf.append(", idleCount "); - buf.append(count); - buf.append(", ["); - for (int i = 0; i < size; ++i) { - if (i != 0) { - buf.append(","); - } - buf.append(System.identityHashCode(checkList.get(i))); - } - buf.append("]"); - LOG.debug(buf.toString()); - } - } for (ConnectionHolder item : evictList) { Connection connection = item.getConnection(); @@ -787,11 +771,11 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat buf.append("evict "); buf.append(evictList.size()); buf.append(", ["); - for (int i = 0; i < size; ++i) { + for (int i = 0; i < evictList.size(); ++i) { if (i != 0) { buf.append(","); } - buf.append(System.identityHashCode(checkList.get(i))); + buf.append(System.identityHashCode(evictList.get(i))); } buf.append("]"); LOG.debug(buf.toString()); @@ -799,7 +783,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } idleList.clear(); - checkList.clear(); evictList.clear(); } catch (InterruptedException e) { break; diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/DataSourceProxy.java b/src/main/java/com/alibaba/druid/proxy/jdbc/DataSourceProxy.java index 26ae6cdcb9..b6967aaca2 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/DataSourceProxy.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/DataSourceProxy.java @@ -42,4 +42,6 @@ public interface DataSourceProxy { long createStatementId(); long createResultSetId(); + + long createTransactionId(); } diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/DataSourceProxyImpl.java b/src/main/java/com/alibaba/druid/proxy/jdbc/DataSourceProxyImpl.java index 75531c1b61..225cab75c8 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/DataSourceProxyImpl.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/DataSourceProxyImpl.java @@ -58,6 +58,7 @@ public class DataSourceProxyImpl implements DataSourceProxy, DataSourceProxyImpl private final AtomicLong connectionIdSeed = new AtomicLong(10000); private final AtomicLong statementIdSeed = new AtomicLong(20000); private final AtomicLong resultSetIdSeed = new AtomicLong(50000); + private final AtomicLong transactionIdSeed = new AtomicLong(0); public DataSourceProxyImpl(Driver rawDriver, DataSourceProxyConfig config){ super(); @@ -442,4 +443,9 @@ public class DataSourceProxyImpl implements DataSourceProxy, DataSourceProxyImpl public long createResultSetId() { return resultSetIdSeed.getAndIncrement(); } + + @Override + public long createTransactionId() { + return transactionIdSeed.getAndIncrement(); + } } diff --git a/src/main/java/com/alibaba/druid/stat/JdbcConnectionStat.java b/src/main/java/com/alibaba/druid/stat/JdbcConnectionStat.java index 757ec8776a..c1724b154a 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcConnectionStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcConnectionStat.java @@ -57,6 +57,7 @@ public class JdbcConnectionStat implements JdbcConnectionStatMBean { private long connectLastTime = 0; private final AtomicLong closeCount = new AtomicLong(0); // 执行Connection.close的计数 + private final AtomicLong transactionStartCount = new AtomicLong(0); private final AtomicLong commitCount = new AtomicLong(0); // 执行commit的计数 private final AtomicLong rollbackCount = new AtomicLong(0); // 执行rollback的计数 @@ -94,6 +95,7 @@ public class JdbcConnectionStat implements JdbcConnectionStatMBean { connectCount.set(0); closeCount.set(0); + transactionStartCount.set(0); commitCount.set(0); rollbackCount.set(0); connectNanoTotal.set(0); @@ -379,6 +381,14 @@ public class JdbcConnectionStat implements JdbcConnectionStatMBean { public void incrementConnectionRollbackCount() { rollbackCount.incrementAndGet(); } + + public void incrementTransactionStartCount() { + transactionStartCount.incrementAndGet(); + } + + public long getTransactionStartCount() { + return transactionStartCount.get(); + } public static class Entry implements EntryMBean {