支持removeAbandoned

git-svn-id: http://code.alibabatech.com/svn/druid/trunk@514 b9813039-fb51-4c41-a8b9-e21c2acb5095
This commit is contained in:
wenshao
2011-07-25 13:24:39 +00:00
parent 26666ed37b
commit f612aa1a7b
4 changed files with 1414 additions and 109 deletions
@@ -30,6 +30,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import javax.security.auth.callback.NameCallback;
@@ -38,9 +39,11 @@ import javax.sql.DataSource;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.FilterChainImpl;
import com.alibaba.druid.pool.DruidDataSource.ActiveConnectionTraceInfo;
import com.alibaba.druid.pool.vendor.NullExceptionSorter;
import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
import com.alibaba.druid.util.ConcurrentIdentityHashMap;
import com.alibaba.druid.util.DruidLoaderUtils;
import com.alibaba.druid.util.JdbcUtils;
@@ -49,20 +52,20 @@ import com.alibaba.druid.util.JdbcUtils;
*/
public abstract class DruidAbstractDataSource implements DruidAbstractDataSourceMBean, DataSource, DataSourceProxy, Serializable {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
public final static int DEFAULT_INITIAL_SIZE = 0;
public final static int DEFAULT_MAX_ACTIVE_SIZE = 8;
public final static int DEFAULT_MAX_IDLE = 8;
public final static int DEFAULT_MIN_IDLE = 0;
public final static int DEFAULT_MAX_WAIT = -1;
public final static String DEFAULT_VALIDATION_QUERY = null; //
public final static boolean DEFAULT_TEST_ON_BORROW = true;
public final static boolean DEFAULT_TEST_ON_RETURN = false;
public final static boolean DEFAULT_WHILE_IDLE = false;
public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
public static final long DEFAULT_TIME_BETWEEN_CONNECT_ERROR_MILLIS = 30 * 1000;
public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
public final static int DEFAULT_INITIAL_SIZE = 0;
public final static int DEFAULT_MAX_ACTIVE_SIZE = 8;
public final static int DEFAULT_MAX_IDLE = 8;
public final static int DEFAULT_MIN_IDLE = 0;
public final static int DEFAULT_MAX_WAIT = -1;
public final static String DEFAULT_VALIDATION_QUERY = null; //
public final static boolean DEFAULT_TEST_ON_BORROW = true;
public final static boolean DEFAULT_TEST_ON_RETURN = false;
public final static boolean DEFAULT_WHILE_IDLE = false;
public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
public static final long DEFAULT_TIME_BETWEEN_CONNECT_ERROR_MILLIS = 30 * 1000;
public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
/**
* The default value for {@link #getMinEvictableIdleTimeMillis}.
@@ -70,82 +73,84 @@ public abstract class DruidAbstractDataSource implements DruidAbstractDataSource
* @see #getMinEvictableIdleTimeMillis
* @see #setMinEvictableIdleTimeMillis
*/
public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;
public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;
protected boolean defaultAutoCommit = false;
protected Boolean defaultReadOnly;
protected Integer defaultTransactionIsolation;
protected String defaultCatalog = null;
protected boolean defaultAutoCommit = false;
protected Boolean defaultReadOnly;
protected Integer defaultTransactionIsolation;
protected String defaultCatalog = null;
protected String name;
protected String name;
protected String username;
protected String password;
protected String jdbcUrl;
protected String driverClass;
protected Properties connectionProperties = new Properties();
protected String username;
protected String password;
protected String jdbcUrl;
protected String driverClass;
protected Properties connectionProperties = new Properties();
protected PasswordCallback passwordCallback;
protected NameCallback userCallback;
protected PasswordCallback passwordCallback;
protected NameCallback userCallback;
protected ConnectionFactory connectionFactory;
protected ConnectionFactory connectionFactory;
protected int initialSize = DEFAULT_INITIAL_SIZE;
protected int maxActive = DEFAULT_MAX_ACTIVE_SIZE;
protected int minIdle = DEFAULT_MIN_IDLE;
protected int maxIdle = DEFAULT_MAX_IDLE;
protected long maxWait = DEFAULT_MAX_WAIT;
protected int initialSize = DEFAULT_INITIAL_SIZE;
protected int maxActive = DEFAULT_MAX_ACTIVE_SIZE;
protected int minIdle = DEFAULT_MIN_IDLE;
protected int maxIdle = DEFAULT_MAX_IDLE;
protected long maxWait = DEFAULT_MAX_WAIT;
protected String validationQuery = DEFAULT_VALIDATION_QUERY;
protected int validationQueryTimeout = -1;
private boolean testOnBorrow = DEFAULT_TEST_ON_BORROW;
private boolean testOnReturn = DEFAULT_TEST_ON_RETURN;
private boolean testWhileIdle = DEFAULT_WHILE_IDLE;
protected boolean poolPreparedStatements = false;
protected String validationQuery = DEFAULT_VALIDATION_QUERY;
protected int validationQueryTimeout = -1;
private boolean testOnBorrow = DEFAULT_TEST_ON_BORROW;
private boolean testOnReturn = DEFAULT_TEST_ON_RETURN;
private boolean testWhileIdle = DEFAULT_WHILE_IDLE;
protected boolean poolPreparedStatements = false;
protected boolean inited = false;
protected boolean inited = false;
protected PrintWriter logWriter = new PrintWriter(System.out);
protected PrintWriter logWriter = new PrintWriter(System.out);
protected List<Filter> filters = new ArrayList<Filter>();
protected ExceptionSorter exceptionSoter = null;
protected List<Filter> filters = new ArrayList<Filter>();
protected ExceptionSorter exceptionSoter = null;
protected Driver driver;
protected Driver driver;
protected int queryTimeout;
protected int queryTimeout;
protected long createErrorCount;
protected long createErrorCount;
protected long createTimespan;
protected long createTimespan;
protected int maxWaitThreadCount = -1;
protected int maxWaitThreadCount = -1;
protected boolean accessToUnderlyingConnectionAllowed = true;
protected boolean accessToUnderlyingConnectionAllowed = true;
protected long timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
protected long timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
protected int numTestsPerEvictionRun = DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
protected int numTestsPerEvictionRun = DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
protected long minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
protected long minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
protected boolean removeAbandoned;
protected boolean removeAbandoned;
protected int removeAbandonedTimeout;
protected int removeAbandonedTimeout;
protected boolean logAbandoned;
protected boolean logAbandoned;
protected int maxOpenPreparedStatements = -1;
protected int maxOpenPreparedStatements = -1;
protected List<String> connectionInitSqls;
protected List<String> connectionInitSqls;
protected String dbType;
protected String dbType;
protected long timeBetweenConnectErrorMillis = DEFAULT_TIME_BETWEEN_CONNECT_ERROR_MILLIS;
protected long timeBetweenConnectErrorMillis = DEFAULT_TIME_BETWEEN_CONNECT_ERROR_MILLIS;
protected ValidConnectionChecker validConnectionChecker = null;
protected ValidConnectionChecker validConnectionChecker = null;
protected final AtomicLong errorCount = new AtomicLong();
protected final AtomicLong dupCloseCount = new AtomicLong();
protected final AtomicLong errorCount = new AtomicLong();
protected final AtomicLong dupCloseCount = new AtomicLong();
protected final ConcurrentIdentityHashMap<PoolableConnection, ActiveConnectionTraceInfo> activeConnections = new ConcurrentIdentityHashMap<PoolableConnection, ActiveConnectionTraceInfo>();
public long getDupCloseCount() {
return dupCloseCount.get();
@@ -789,6 +794,28 @@ public abstract class DruidAbstractDataSource implements DruidAbstractDataSource
}
}
public Set<PoolableConnection> getActiveConnections() {
return this.activeConnections.keySet();
}
void removeActiveConnection(PoolableConnection conn) {
activeConnections.remove(conn);
}
public List<String> getActiveConnectionStackTrace() {
List<String> list = new ArrayList<String>();
for (ActiveConnectionTraceInfo traceInfo : this.activeConnections.values()) {
StringBuilder buf = new StringBuilder();
for (StackTraceElement item : traceInfo.getStackTrace()) {
buf.append(item.toString());
buf.append("\n");
}
list.add(buf.toString());
}
return list;
}
public long getCreateTimespanNano() {
return createTimespan;
}
@@ -21,7 +21,6 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -53,6 +52,7 @@ import com.alibaba.druid.proxy.DruidDriver;
import com.alibaba.druid.proxy.jdbc.DataSourceProxyConfig;
import com.alibaba.druid.stat.JdbcDataSourceStat;
import com.alibaba.druid.stat.JdbcStatManager;
import com.alibaba.druid.util.ConcurrentIdentityHashMap;
import com.alibaba.druid.util.JdbcUtils;
/**
@@ -60,45 +60,43 @@ import com.alibaba.druid.util.JdbcUtils;
*/
public class DruidDataSource extends DruidAbstractDataSource implements DruidDataSourceMBean, ManagedDataSource, Referenceable {
private final static Log LOG = LogFactory.getLog(DruidDataSource.class);
private final static Log LOG = LogFactory.getLog(DruidDataSource.class);
private static final Object PRESENT = new Object();
private static final IdentityHashMap<DruidDataSource, Object> instances = new IdentityHashMap<DruidDataSource, Object>();
private static final Object PRESENT = new Object();
private static final ConcurrentIdentityHashMap<DruidDataSource, Object> instances = new ConcurrentIdentityHashMap<DruidDataSource, Object>();
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
private final ReentrantLock lock = new ReentrantLock();
private final ReentrantLock lock = new ReentrantLock();
private final Condition notEmpty = lock.newCondition();
private final Condition notMaxActive = lock.newCondition();
private final Condition lowWater = lock.newCondition();
private final Condition notEmpty = lock.newCondition();
private final Condition notMaxActive = lock.newCondition();
private final Condition lowWater = lock.newCondition();
// stats
private long connectCount = 0;
private long closeCount = 0;
private long connectErrorCount = 0;
private long recycleCount = 0;
private long createConnectionCount = 0L;
private long destroyCount = 0;
private long connectCount = 0;
private long closeCount = 0;
private long connectErrorCount = 0;
private long recycleCount = 0;
private long createConnectionCount = 0L;
private long destroyCount = 0;
// store
private ConnectionHolder[] connections;
private int count = 0;
private int activeCount = 0;
private long idleCheckCount = 0;
private ConnectionHolder[] connections;
private int count = 0;
private int activeCount = 0;
private long idleCheckCount = 0;
// threads
private CreateConnectionThread createConnectionThread;
private DestroyConnectionThread destoryConnectionThread;
private CreateConnectionThread createConnectionThread;
private DestroyConnectionThread destoryConnectionThread;
private final IdentityHashMap<PoolableConnection, ActiveConnectionTraceInfo> activeConnections = new IdentityHashMap<PoolableConnection, ActiveConnectionTraceInfo>();
private final CountDownLatch initedLatch = new CountDownLatch(2);
private final CountDownLatch initedLatch = new CountDownLatch(2);
private long id;
private Date createdTime;
private long id;
private Date createdTime;
private boolean enable = true;
private boolean enable = true;
public DruidDataSource(){
}
@@ -242,10 +240,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
public Set<PoolableConnection> getActiveConnections() {
return this.activeConnections.keySet();
}
@Override
public Connection getConnection() throws SQLException {
init();
@@ -318,7 +312,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
poolalbeConnection = new PoolableConnection(holder);
if (removeAbandoned) {
if (isRemoveAbandoned()) {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
activeConnections.put(poolalbeConnection, new ActiveConnectionTraceInfo(poolalbeConnection, System.currentTimeMillis(), stackTrace));
}
@@ -808,21 +802,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
@Override
public List<String> getActiveConnectionStackTrace() {
List<String> list = new ArrayList<String>();
for (ActiveConnectionTraceInfo traceInfo : this.activeConnections.values()) {
StringBuilder buf = new StringBuilder();
for (StackTraceElement item : traceInfo.getStackTrace()) {
buf.append(item.toString());
buf.append("\n");
}
list.add(buf.toString());
}
return list;
}
@Override
public List<String> getFilterClassNames() {
List<String> names = new ArrayList<String>();
@@ -135,7 +135,7 @@ public class PoolableConnection implements PooledConnection, Connection {
DruidAbstractDataSource dataSource = holder.getDataSource();
if (dataSource.isRemoveAbandoned()) {
dataSource.getActiveConnectionStackTrace().remove(this);
dataSource.removeActiveConnection(this);
}
for (ConnectionEventListener listener : holder.getConnectionEventListeners()) {
File diff suppressed because it is too large Load Diff