赞
踩
目录
首先声明:这个锅不是 DruidDataSource的问题,请放心使用 DruidDataSource。
DS是关系型数据库服务(Relational Database Service)的简称,是一种即开即用、稳定可靠、可弹性伸缩的在线数据库服务。具有多重安全防护措施和完善的性能监控体系,并提供专业的数据库备份、恢复及优化方案,使您能专注于应用开发和业务发展。
问题描述:使用JDBC和Hikari连接RDS都可以正常启动服务,使用DruidDataSource连接RDS却启动不起来,最后是因为程序授权 license导致服务启动失败,而DruidDataSource的警告异常是系统安全级别的提示而已 。
主要提示的是sun.misc.Unsafe.park(Native method) ,此问题可能是系统级别的安全限制,虽然也有AQS异常,本质上应该涉及到系统Native方法调用。
- sun.misc.Unsafe.park(Native Method)
- java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
- java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
- com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2576)
- 17-Sep-2020 18:09:21.112 WARNING [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [forestar-patrol-ywpt] appears to have started a thread named [Druid-ConnectionPool-Destroy-869651846] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
- java.lang.Thread.sleep(Native Method)
- com.alibaba.druid.pool.DruidDataSource$DestroyConnectionThread.run(DruidDataSource.java:2672)
- 17-Sep-2020 18:09:21.113 WARNING [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [forestar-patrol-ywpt] appears to have started a thread named [fsCacheManager] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
- java.net.SocketInputStream.socketRead0(Native Method)
- java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
- java.net.SocketInputStream.read(SocketInputStream.java:171)
- java.net.SocketInputStream.read(SocketInputStream.java:141)
- java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
- java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
- java.io.BufferedInputStream.read(BufferedInputStream.java:345)
- sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:735)
- sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)
- sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
- sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
- net.sf.ehcache.util.UpdateChecker.getUpdateProperties(UpdateChecker.java:106)
- net.sf.ehcache.util.UpdateChecker.doCheck(UpdateChecker.java:70)
- net.sf.ehcache.util.UpdateChecker.checkForUpdate(UpdateChecker.java:60)
- net.sf.ehcache.util.UpdateChecker.run(UpdateChecker.java:51)
- java.util.TimerThread.mainLoop(Timer.java:555)
- java.util.TimerThread.run(Timer.java:505)
- 17-Sep-2020 18:09:21.113 WARNING [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [forestar-patrol-ywpt] appears to have started a thread named [SimplePageCachingFilter.data] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
- sun.misc.Unsafe.park(Native Method)
- java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
- java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
- java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
- java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
- java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
- java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
- java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
- java.lang.Thread.run(Thread.java:748)
- 17-Sep-2020 18:09:21.114 WARNING [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [forestar-patrol-ywpt] appears to have started a thread named [MedataCache.data] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
- sun.misc.Unsafe.park(Native Method)
- java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
- java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
- java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
- java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
- java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
- java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
- java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
- java.lang.Thread.run(Thread.java:748)
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack.png)
错误点1:
错误点2:
错误点1分析:这里是AQS队列阻塞。
定位到park底层调用的是Native方法:这里就是将线程的进行阻塞的方法。
setBlocker方法本身是调用本地系统Native硬件方法:
而UNSAFE的方法都是本地硬件Native方法:
问题点2是同个线程引发的问题实质上是问题1。
阿里Druid项目代码:https://github.com/alibaba/druid
解决方法参考:RDS的mysql无法正常连接 ,或者更换数据源
- /*
- * Copyright 1999-2018 Alibaba Group Holding Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.alibaba.druid.pool;
-
- import static com.alibaba.druid.util.Utils.getBoolean;
-
- import java.io.Closeable;
- import java.security.AccessController;
- import java.security.PrivilegedAction;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.sql.Statement;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.ConcurrentModificationException;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.LinkedHashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Properties;
- import java.util.ServiceLoader;
- import java.util.StringTokenizer;
- import java.util.TimeZone;
- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.Future;
- import java.util.concurrent.ScheduledFuture;
- import java.util.concurrent.ScheduledThreadPoolExecutor;
- import java.util.concurrent.TimeUnit;
- import java.util.concurrent.atomic.AtomicLongFieldUpdater;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
-
- import javax.management.JMException;
- import javax.management.MBeanRegistration;
- import javax.management.MBeanServer;
- import javax.management.ObjectName;
- 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 javax.sql.ConnectionPoolDataSource;
- import javax.sql.PooledConnection;
-
- import com.alibaba.druid.Constants;
- import com.alibaba.druid.TransactionTimeoutException;
- import com.alibaba.druid.VERSION;
- import com.alibaba.druid.filter.AutoLoad;
- import com.alibaba.druid.filter.Filter;
- import com.alibaba.druid.filter.FilterChainImpl;
- import com.alibaba.druid.mock.MockDriver;
- import com.alibaba.druid.pool.DruidPooledPreparedStatement.PreparedStatementKey;
- import com.alibaba.druid.pool.vendor.DB2ExceptionSorter;
- import com.alibaba.druid.pool.vendor.InformixExceptionSorter;
- import com.alibaba.druid.pool.vendor.MSSQLValidConnectionChecker;
- import com.alibaba.druid.pool.vendor.MockExceptionSorter;
- import com.alibaba.druid.pool.vendor.MySqlExceptionSorter;
- import com.alibaba.druid.pool.vendor.MySqlValidConnectionChecker;
- import com.alibaba.druid.pool.vendor.NullExceptionSorter;
- import com.alibaba.druid.pool.vendor.OracleExceptionSorter;
- import com.alibaba.druid.pool.vendor.OracleValidConnectionChecker;
- import com.alibaba.druid.pool.vendor.PGExceptionSorter;
- import com.alibaba.druid.pool.vendor.PGValidConnectionChecker;
- import com.alibaba.druid.pool.vendor.SybaseExceptionSorter;
- import com.alibaba.druid.proxy.DruidDriver;
- import com.alibaba.druid.proxy.jdbc.DataSourceProxyConfig;
- import com.alibaba.druid.proxy.jdbc.TransactionInfo;
- import com.alibaba.druid.sql.ast.SQLStatement;
- import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
- import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
- import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
- import com.alibaba.druid.sql.parser.SQLParserUtils;
- import com.alibaba.druid.sql.parser.SQLStatementParser;
- import com.alibaba.druid.stat.DruidDataSourceStatManager;
- import com.alibaba.druid.stat.JdbcDataSourceStat;
- import com.alibaba.druid.stat.JdbcSqlStat;
- import com.alibaba.druid.stat.JdbcSqlStatValue;
- import com.alibaba.druid.support.logging.Log;
- import com.alibaba.druid.support.logging.LogFactory;
- import com.alibaba.druid.util.JMXUtils;
- import com.alibaba.druid.util.JdbcConstants;
- import com.alibaba.druid.util.JdbcUtils;
- import com.alibaba.druid.util.StringUtils;
- import com.alibaba.druid.util.Utils;
- import com.alibaba.druid.wall.WallFilter;
- import com.alibaba.druid.wall.WallProviderStatValue;
-
- /**
- * @author ljw [ljw2083@alibaba-inc.com]
- * @author wenshao [szujobs@hotmail.com]
- */
- public class DruidDataSource extends DruidAbstractDataSource implements DruidDataSourceMBean, ManagedDataSource, Referenceable, Closeable, Cloneable, ConnectionPoolDataSource, MBeanRegistration {
-
- private final static Log LOG = LogFactory.getLog(DruidDataSource.class);
- private static final long serialVersionUID = 1L;
- // stats
- private volatile long recycleErrorCount = 0L;
- private long connectCount = 0L;
- private long closeCount = 0L;
- private volatile long connectErrorCount = 0L;
- private long recycleCount = 0L;
- private long removeAbandonedCount = 0L;
- private long notEmptyWaitCount = 0L;
- private long notEmptySignalCount = 0L;
- private long notEmptyWaitNanos = 0L;
- private int keepAliveCheckCount = 0;
- private int activePeak = 0;
- private long activePeakTime = 0;
- private int poolingPeak = 0;
- private long poolingPeakTime = 0;
- // store
- private volatile DruidConnectionHolder[] connections;
- private int poolingCount = 0;
- private int activeCount = 0;
- private volatile long discardCount = 0;
- private int notEmptyWaitThreadCount = 0;
- private int notEmptyWaitThreadPeak = 0;
- //
- private DruidConnectionHolder[] evictConnections;
- private DruidConnectionHolder[] keepAliveConnections;
-
- // threads
- private volatile ScheduledFuture<?> destroySchedulerFuture;
- private DestroyTask destroyTask;
-
- private volatile Future<?> createSchedulerFuture;
-
- private CreateConnectionThread createConnectionThread;
- private DestroyConnectionThread destroyConnectionThread;
- private LogStatsThread logStatsThread;
- private int createTaskCount;
-
- private final CountDownLatch initedLatch = new CountDownLatch(2);
-
- private volatile boolean enable = true;
-
- private boolean resetStatEnable = true;
- private volatile long resetCount = 0L;
-
- private String initStackTrace;
-
- private volatile boolean closing = false;
- private volatile boolean closed = false;
- private long closeTimeMillis = -1L;
-
- protected JdbcDataSourceStat dataSourceStat;
-
- private boolean useGlobalDataSourceStat = false;
- private boolean mbeanRegistered = false;
- public static ThreadLocal<Long> waitNanosLocal = new ThreadLocal<Long>();
- private boolean logDifferentThread = true;
- private volatile boolean keepAlive = false;
- private boolean asyncInit = false;
- protected boolean killWhenSocketReadTimeout = false;
-
- private static List<Filter> autoFilters = null;
- private boolean loadSpifilterSkip = false;
-
- protected static final AtomicLongFieldUpdater<DruidDataSource> recycleErrorCountUpdater
- = AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "recycleErrorCount");
- protected static final AtomicLongFieldUpdater<DruidDataSource> connectErrorCountUpdater
- = AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "connectErrorCount");
- protected static final AtomicLongFieldUpdater<DruidDataSource> resetCountUpdater
- = AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "resetCount");
-
-
- public DruidDataSource(){
- this(false);
- }
-
- public DruidDataSource(boolean fairLock){
- super(fairLock);
-
- configFromPropety(System.getProperties());
- }
-
- public boolean isAsyncInit() {
- return asyncInit;
- }
-
- public void setAsyncInit(boolean asyncInit) {
- this.asyncInit = asyncInit;
- }
-
- public void configFromPropety(Properties properties) {
- {
- String property = properties.getProperty("druid.name");
- if (property != null) {
- this.setName(property);
- }
- }
- {
- String property = properties.getProperty("druid.url");
- if (property != null) {
- this.setUrl(property);
- }
- }
- {
- String property = properties.getProperty("druid.username");
- if (property != null) {
- this.setUsername(property);
- }
- }
- {
- String property = properties.getProperty("druid.password");
- if (property != null) {
- this.setPassword(property);
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.testWhileIdle");
- if (value != null) {
- this.testWhileIdle = value;
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.testOnBorrow");
- if (value != null) {
- this.testOnBorrow = value;
- }
- }
- {
- String property = properties.getProperty("druid.validationQuery");
- if (property != null && property.length() > 0) {
- this.setValidationQuery(property);
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.useGlobalDataSourceStat");
- if (value != null) {
- this.setUseGlobalDataSourceStat(value);
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.useGloalDataSourceStat"); // compatible for early versions
- if (value != null) {
- this.setUseGlobalDataSourceStat(value);
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.asyncInit"); // compatible for early versions
- if (value != null) {
- this.setAsyncInit(value);
- }
- }
- {
- String property = properties.getProperty("druid.filters");
-
- if (property != null && property.length() > 0) {
- try {
- this.setFilters(property);
- } catch (SQLException e) {
- LOG.error("setFilters error", e);
- }
- }
- }
- {
- String property = properties.getProperty(Constants.DRUID_TIME_BETWEEN_LOG_STATS_MILLIS);
- if (property != null && property.length() > 0) {
- try {
- long value = Long.parseLong(property);
- this.setTimeBetweenLogStatsMillis(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property '" + Constants.DRUID_TIME_BETWEEN_LOG_STATS_MILLIS + "'", e);
- }
- }
- }
- {
- String property = properties.getProperty(Constants.DRUID_STAT_SQL_MAX_SIZE);
- if (property != null && property.length() > 0) {
- try {
- int value = Integer.parseInt(property);
- if (dataSourceStat != null) {
- dataSourceStat.setMaxSqlSize(value);
- }
- } catch (NumberFormatException e) {
- LOG.error("illegal property '" + Constants.DRUID_STAT_SQL_MAX_SIZE + "'", e);
- }
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.clearFiltersEnable");
- if (value != null) {
- this.setClearFiltersEnable(value);
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.resetStatEnable");
- if (value != null) {
- this.setResetStatEnable(value);
- }
- }
- {
- String property = properties.getProperty("druid.notFullTimeoutRetryCount");
- if (property != null && property.length() > 0) {
- try {
- int value = Integer.parseInt(property);
- this.setNotFullTimeoutRetryCount(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.notFullTimeoutRetryCount'", e);
- }
- }
- }
- {
- String property = properties.getProperty("druid.timeBetweenEvictionRunsMillis");
- if (property != null && property.length() > 0) {
- try {
- long value = Long.parseLong(property);
- this.setTimeBetweenEvictionRunsMillis(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.timeBetweenEvictionRunsMillis'", e);
- }
- }
- }
- {
- String property = properties.getProperty("druid.maxWaitThreadCount");
- if (property != null && property.length() > 0) {
- try {
- int value = Integer.parseInt(property);
- this.setMaxWaitThreadCount(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.maxWaitThreadCount'", e);
- }
- }
- }
- {
- String property = properties.getProperty("druid.maxWait");
- if (property != null && property.length() > 0) {
- try {
- int value = Integer.parseInt(property);
- this.setMaxWait(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.maxWait'", e);
- }
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.failFast");
- if (value != null) {
- this.setFailFast(value);
- }
- }
- {
- String property = properties.getProperty("druid.phyTimeoutMillis");
- if (property != null && property.length() > 0) {
- try {
- long value = Long.parseLong(property);
- this.setPhyTimeoutMillis(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.phyTimeoutMillis'", e);
- }
- }
- }
- {
- String property = properties.getProperty("druid.phyMaxUseCount");
- if (property != null && property.length() > 0) {
- try {
- long value = Long.parseLong(property);
- this.setPhyMaxUseCount(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.phyMaxUseCount'", e);
- }
- }
- }
- {
- String property = properties.getProperty("druid.minEvictableIdleTimeMillis");
- if (property != null && property.length() > 0) {
- try {
- long value = Long.parseLong(property);
- this.setMinEvictableIdleTimeMillis(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.minEvictableIdleTimeMillis'", e);
- }
- }
- }
- {
- String property = properties.getProperty("druid.maxEvictableIdleTimeMillis");
- if (property != null && property.length() > 0) {
- try {
- long value = Long.parseLong(property);
- this.setMaxEvictableIdleTimeMillis(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.maxEvictableIdleTimeMillis'", e);
- }
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.keepAlive");
- if (value != null) {
- this.setKeepAlive(value);
- }
- }
- {
- String property = properties.getProperty("druid.keepAliveBetweenTimeMillis");
- if (property != null && property.length() > 0) {
- try {
- long value = Long.parseLong(property);
- this.setKeepAliveBetweenTimeMillis(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.keepAliveBetweenTimeMillis'", e);
- }
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.poolPreparedStatements");
- if (value != null) {
- this.setPoolPreparedStatements0(value);
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.initVariants");
- if (value != null) {
- this.setInitVariants(value);
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.initGlobalVariants");
- if (value != null) {
- this.setInitGlobalVariants(value);
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.useUnfairLock");
- if (value != null) {
- this.setUseUnfairLock(value);
- }
- }
- {
- String property = properties.getProperty("druid.driverClassName");
- if (property != null) {
- this.setDriverClassName(property);
- }
- }
- {
- String property = properties.getProperty("druid.initialSize");
- if (property != null && property.length() > 0) {
- try {
- int value = Integer.parseInt(property);
- this.setInitialSize(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.initialSize'", e);
- }
- }
- }
- {
- String property = properties.getProperty("druid.minIdle");
- if (property != null && property.length() > 0) {
- try {
- int value = Integer.parseInt(property);
- this.setMinIdle(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.minIdle'", e);
- }
- }
- }
- {
- String property = properties.getProperty("druid.maxActive");
- if (property != null && property.length() > 0) {
- try {
- int value = Integer.parseInt(property);
- this.setMaxActive(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.maxActive'", e);
- }
- }
- }
- {
- Boolean value = getBoolean(properties, "druid.killWhenSocketReadTimeout");
- if (value != null) {
- setKillWhenSocketReadTimeout(value);
- }
- }
- {
- String property = properties.getProperty("druid.connectProperties");
- if (property != null) {
- this.setConnectionProperties(property);
- }
- }
- {
- String property = properties.getProperty("druid.maxPoolPreparedStatementPerConnectionSize");
- if (property != null && property.length() > 0) {
- try {
- int value = Integer.parseInt(property);
- this.setMaxPoolPreparedStatementPerConnectionSize(value);
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.maxPoolPreparedStatementPerConnectionSize'", e);
- }
- }
- }
- {
- String property = properties.getProperty("druid.initConnectionSqls");
- if (property != null && property.length() > 0) {
- try {
- StringTokenizer tokenizer = new StringTokenizer(property, ";");
- setConnectionInitSqls(Collections.list(tokenizer));
- } catch (NumberFormatException e) {
- LOG.error("illegal property 'druid.initConnectionSqls'", e);
- }
- }
- }
- {
- String property = System.getProperty("druid.load.spifilter.skip");
- if (property != null && !"false".equals(property)) {
- loadSpifilterSkip = true;
- }
- }
- }
-
- public boolean isKillWhenSocketReadTimeout() {
- return killWhenSocketReadTimeout;
- }
-
- public void setKillWhenSocketReadTimeout(boolean killWhenSocketTimeOut) {
- this.killWhenSocketReadTimeout = killWhenSocketTimeOut;
- }
-
- public boolean isUseGlobalDataSourceStat() {
- return useGlobalDataSourceStat;
- }
-
- public void setUseGlobalDataSourceStat(boolean useGlobalDataSourceStat) {
- this.useGlobalDataSourceStat = useGlobalDataSourceStat;
- }
-
- public boolean isKeepAlive() {
- return keepAlive;
- }
-
- public void setKeepAlive(boolean keepAlive) {
- this.keepAlive = keepAlive;
- }
-
- public String getInitStackTrace() {
- return initStackTrace;
- }
-
- public boolean isResetStatEnable() {
- return resetStatEnable;
- }
-
- public void setResetStatEnable(boolean resetStatEnable) {
- this.resetStatEnable = resetStatEnable;
- if (dataSourceStat != null) {
- dataSourceStat.setResetStatEnable(resetStatEnable);
- }
- }
-
- public long getDiscardCount() {
- return discardCount;
- }
-
- public void restart() throws SQLException {
- lock.lock();
- try {
- if (activeCount > 0) {
- throw new SQLException("can not restart, activeCount not zero. " + activeCount);
- }
- if (LOG.isInfoEnabled()) {
- LOG.info("{dataSource-" + this.getID() + "} restart");
- }
-
- this.close();
- this.resetStat();
- this.inited = false;
- this.enable = true;
- this.closed = false;
- } finally {
- lock.unlock();
- }
- }
-
- public void resetStat() {
- if (!isResetStatEnable()) {
- return;
- }
-
- lock.lock();
- try {
- connectCount = 0;
- closeCount = 0;
- discardCount = 0;
- recycleCount = 0;
- createCount = 0L;
- directCreateCount = 0;
- destroyCount = 0L;
- removeAbandonedCount = 0;
- notEmptyWaitCount = 0;
- notEmptySignalCount = 0L;
- notEmptyWaitNanos = 0;
-
- activePeak = activeCount;
- activePeakTime = 0;
- poolingPeak = 0;
- createTimespan = 0;
- lastError = null;
- lastErrorTimeMillis = 0;
- lastCreateError = null;
- lastCreateErrorTimeMillis = 0;
- } finally {
- lock.unlock();
- }
-
- connectErrorCountUpdater.set(this, 0);
- errorCountUpdater.set(this, 0);
- commitCountUpdater.set(this, 0);
- rollbackCountUpdater.set(this, 0);
- startTransactionCountUpdater.set(this, 0);
- cachedPreparedStatementHitCountUpdater.set(this, 0);
- closedPreparedStatementCountUpdater.set(this, 0);
- preparedStatementCountUpdater.set(this, 0);
- transactionHistogram.reset();
- cachedPreparedStatementDeleteCountUpdater.set(this, 0);
- recycleErrorCountUpdater.set(this, 0);
-
- resetCountUpdater.incrementAndGet(this);
- }
-
- public long getResetCount() {
- return this.resetCount;
- }
-
- public boolean isEnable() {
- return enable;
- }
-
- public void setEnable(boolean enable) {
- lock.lock();
- try {
- this.enable = enable;
- if (!enable) {
- notEmpty.signalAll();
- notEmptySignalCount++;
- }
- } finally {
- lock.unlock();
- }
- }
-
- public void setPoolPreparedStatements(boolean value) {
- setPoolPreparedStatements0(value);
- }
-
- private void setPoolPreparedStatements0(boolean value) {
- if (this.poolPreparedStatements == value) {
- return;
- }
-
- this.poolPreparedStatements = value;
-
- if (!inited) {
- return;
- }
-
- if (LOG.isInfoEnabled()) {
- LOG.info("set poolPreparedStatements " + this.poolPreparedStatements + " -> " + value);
- }
-
- if (!value) {
- lock.lock();
- try {
-
- for (int i = 0; i < poolingCount; ++i) {
- DruidConnectionHolder connection = connections[i];
-
- for (PreparedStatementHolder holder : connection.getStatementPool().getMap().values()) {
- closePreapredStatement(holder);
- }
-
- connection.getStatementPool().getMap().clear();
- }
- } finally {
- lock.unlock();
- }
- }
- }
-
- public void setMaxActive(int maxActive) {
- if (this.maxActive == maxActive) {
- return;
- }
-
- if (maxActive == 0) {
- throw new IllegalArgumentException("maxActive can't not set zero");
- }
-
- if (!inited) {
- this.maxActive = maxActive;
- return;
- }
-
- if (maxActive < this.minIdle) {
- throw new IllegalArgumentException("maxActive less than minIdle, " + maxActive + " < " + this.minIdle);
- }
-
- if (LOG.isInfoEnabled()) {
- LOG.info("maxActive changed : " + this.maxActive + " -> " + maxActive);
- }
-
- lock.lock();
- try {
- int allCount = this.poolingCount + this.activeCount;
-
- if (maxActive > allCount) {
- this.connections = Arrays.copyOf(this.connections, maxActive);
- evictConnections = new DruidConnectionHolder[maxActive];
- keepAliveConnections = new DruidConnectionHolder[maxActive];
- } else {
- this.connections = Arrays.copyOf(this.connections, allCount);
- evictConnections = new DruidConnectionHolder[allCount];
- keepAliveConnections = new DruidConnectionHolder[allCount];
- }
-
- this.maxActive = maxActive;
- } finally {
- lock.unlock();
- }
- }
-
- @SuppressWarnings("rawtypes")
- public void setConnectProperties(Properties properties) {
- if (properties == null) {
- properties = new Properties();
- }
-
- boolean equals;
- if (properties.size() == this.connectProperties.size()) {
- equals = true;
- for (Map.Entry entry : properties.entrySet()) {
- Object value = this.connectProperties.get(entry.getKey());
- Object entryValue = entry.getValue();
- if (value == null && entryValue != null) {
- equals = false;
- break;
- }
-
- if (!value.equals(entry.getValue())) {
- equals = false;
- break;
- }
- }
- } else {
- equals = false;
- }
-
- if (!equals) {
- if (inited && LOG.isInfoEnabled()) {
- LOG.info("connectProperties changed : " + this.connectProperties + " -> " + properties);
- }
-
- configFromPropety(properties);
-
- for (Filter filter : this.filters) {
- filter.configFromProperties(properties);
- }
-
- if (exceptionSorter != null) {
- exceptionSorter.configFromProperties(properties);
- }
-
- if (validConnectionChecker != null) {
- validConnectionChecker.configFromProperties(properties);
- }
-
- if (statLogger != null) {
- statLogger.configFromProperties(properties);
- }
- }
-
- this.connectProperties = properties;
- }
-
- public void init() throws SQLException {
- if (inited) {
- return;
- }
-
- // bug fixed for dead lock, for issue #2980
- DruidDriver.getInstance();
-
- final ReentrantLock lock = this.lock;
- try {
- lock.lockInterruptibly();
- } catch (InterruptedException e) {
- throw new SQLException("interrupt", e);
- }
-
- boolean init = false;
- try {
- if (inited) {
- return;
- }
-
- initStackTrace = Utils.toString(Thread.currentThread().getStackTrace());
-
- this.id = DruidDriver.createDataSourceId();
- if (this.id > 1) {
- long delta = (this.id - 1) * 100000;
- this.connectionIdSeedUpdater.addAndGet(this, delta);
- this.statementIdSeedUpdater.addAndGet(this, delta);
- this.resultSetIdSeedUpdater.addAndGet(this, delta);
- this.transactionIdSeedUpdater.addAndGet(this, delta);
- }
-
- if (this.jdbcUrl != null) {
- this.jdbcUrl = this.jdbcUrl.trim();
- initFromWrapDriverUrl();
- }
-
- for (Filter filter : filters) {
- filter.init(this);
- }
-
- if (this.dbType == null || this.dbType.length() == 0) {
- this.dbType = JdbcUtils.getDbType(jdbcUrl, null);
- }
-
- if (JdbcConstants.MYSQL.equals(this.dbType)
- || JdbcConstants.MARIADB.equals(this.dbType)
- || JdbcConstants.ALIYUN_ADS.equals(this.dbType)) {
- boolean cacheServerConfigurationSet = false;
- if (this.connectProperties.containsKey("cacheServerConfiguration")) {
- cacheServerConfigurationSet = true;
- } else if (this.jdbcUrl.indexOf("cacheServerConfiguration") != -1) {
- cacheServerConfigurationSet = true;
- }
- if (cacheServerConfigurationSet) {
- this.connectProperties.put("cacheServerConfiguration", "true");
- }
- }
-
- if (maxActive <= 0) {
- throw new IllegalArgumentException("illegal maxActive " + maxActive);
- }
-
- if (maxActive < minIdle) {
- throw new IllegalArgumentException("illegal maxActive " + maxActive);
- }
-
- if (getInitialSize() > maxActive) {
- throw new IllegalArgumentException("illegal initialSize " + this.initialSize + ", maxActive " + maxActive);
- }
-
- if (timeBetweenLogStatsMillis > 0 && useGlobalDataSourceStat) {
- throw new IllegalArgumentException("timeBetweenLogStatsMillis not support useGlobalDataSourceStat=true");
- }
-
- if (maxEvictableIdleTimeMillis < minEvictableIdleTimeMillis) {
- throw new SQLException("maxEvictableIdleTimeMillis must be grater than minEvictableIdleTimeMillis");
- }
-
- if (this.driverClass != null) {
- this.driverClass = driverClass.trim();
- }
-
- initFromSPIServiceLoader();
-
- if (this.driver == null) {
- if (this.driverClass == null || this.driverClass.isEmpty()) {
- this.driverClass = JdbcUtils.getDriverClassName(this.jdbcUrl);
- }
-
- if (MockDriver.class.getName().equals(driverClass)) {
- driver = MockDriver.instance;
- } else {
- if (jdbcUrl == null && (driverClass == null || driverClass.length() == 0)) {
- throw new SQLException("url not set");
- }
- driver = JdbcUtils.createDriver(driverClassLoader, driverClass);
- }
- } else {
- if (this.driverClass == null) {
- this.driverClass = driver.getClass().getName();
- }
- }
-
- initCheck();
-
- initExceptionSorter();
- initValidConnectionChecker();
- validationQueryCheck();
-
- if (isUseGlobalDataSourceStat()) {
- dataSourceStat = JdbcDataSourceStat.getGlobal();
- if (dataSourceStat == null) {
- dataSourceStat = new JdbcDataSourceStat("Global", "Global", this.dbType);
- JdbcDataSourceStat.setGlobal(dataSourceStat);
- }
- if (dataSourceStat.getDbType() == null) {
- dataSourceStat.setDbType(this.dbType);
- }
- } else {
- dataSourceStat = new JdbcDataSourceStat(this.name, this.jdbcUrl, this.dbType, this.connectProperties);
- }
- dataSourceStat.setResetStatEnable(this.resetStatEnable);
-
- connections = new DruidConnectionHolder[maxActive];
- evictConnections = new DruidConnectionHolder[maxActive];
- keepAliveConnections = new DruidConnectionHolder[maxActive];
-
- SQLException connectError = null;
-
- if (createScheduler != null && asyncInit) {
- for (int i = 0; i < initialSize; ++i) {
- createTaskCount++;
- CreateConnectionTask task = new CreateConnectionTask(true);
- this.createSchedulerFuture = createScheduler.submit(task);
- }
- } else if (!asyncInit) {
- // init connections
- while (poolingCount < initialSize) {
- try {
- PhysicalConnectionInfo pyConnectInfo = createPhysicalConnection();
- DruidConnectionHolder holder = new DruidConnectionHolder(this, pyConnectInfo);
- connections[poolingCount++] = holder;
- } catch (SQLException ex) {
- LOG.error("init datasource error, url: " + this.getUrl(), ex);
- if (initExceptionThrow) {
- connectError = ex;
- break;
- } else {
- Thread.sleep(3000);
- }
- }
- }
-
- if (poolingCount > 0) {
- poolingPeak = poolingCount;
- poolingPeakTime = System.currentTimeMillis();
- }
- }
-
- createAndLogThread();
- createAndStartCreatorThread();
- createAndStartDestroyThread();
-
- initedLatch.await();
- init = true;
-
- initedTime = new Date();
- registerMbean();
-
- if (connectError != null && poolingCount == 0) {
- throw connectError;
- }
-
- if (keepAlive) {
- // async fill to minIdle
- if (createScheduler != null) {
- for (int i = 0; i < minIdle; ++i) {
- createTaskCount++;
- CreateConnectionTask task = new CreateConnectionTask(true);
- this.createSchedulerFuture = createScheduler.submit(task);
- }
- } else {
- this.emptySignal();
- }
- }
-
- } catch (SQLException e) {
- LOG.error("{dataSource-" + this.getID() + "} init error", e);
- throw e;
- } catch (InterruptedException e) {
- throw new SQLException(e.getMessage(), e);
- } catch (RuntimeException e){
- LOG.error("{dataSource-" + this.getID() + "} init error", e);
- throw e;
- } catch (Error e){
- LOG.error("{dataSource-" + this.getID() + "} init error", e);
- throw e;
-
- } finally {
- inited = true;
- lock.unlock();
-
- if (init && LOG.isInfoEnabled()) {
- String msg = "{dataSource-" + this.getID();
-
- if (this.name != null && !this.name.isEmpty()) {
- msg += ",";
- msg += this.name;
- }
-
- msg += "} inited";
-
- LOG.info(msg);
- }
- }
- }
-
- private void createAndLogThread() {
- if (this.timeBetweenLogStatsMillis <= 0) {
- return;
- }
-
- String threadName = "Druid-ConnectionPool-Log-" + System.identityHashCode(this);
- logStatsThread = new LogStatsThread(threadName);
- logStatsThread.start();
-
- this.resetStatEnable = false;
- }
-
- protected void createAndStartDestroyThread() {
- destroyTask = new DestroyTask();
-
- if (destroyScheduler != null) {
- long period = timeBetweenEvictionRunsMillis;
- if (period <= 0) {
- period = 1000;
- }
- destroySchedulerFuture = destroyScheduler.scheduleAtFixedRate(destroyTask, period, period,
- TimeUnit.MILLISECONDS);
- initedLatch.countDown();
- return;
- }
-
- String threadName = "Druid-ConnectionPool-Destroy-" + System.identityHashCode(this);
- destroyConnectionThread = new DestroyConnectionThread(threadName);
- destroyConnectionThread.start();
- }
-
- protected void createAndStartCreatorThread() {
- if (createScheduler == null) {
- String threadName = "Druid-ConnectionPool-Create-" + System.identityHashCode(this);
- createConnectionThread = new CreateConnectionThread(threadName);
- createConnectionThread.start();
- return;
- }
-
- initedLatch.countDown();
- }
-
- /**
- * load filters from SPI ServiceLoader
- *
- * @see ServiceLoader
- */
- private void initFromSPIServiceLoader() {
- if (loadSpifilterSkip) {
- return;
- }
-
- if (autoFilters == null) {
- List<Filter> filters = new ArrayList<Filter>();
- ServiceLoader<Filter> autoFilterLoader = ServiceLoader.load(Filter.class);
-
- for (Filter filter : autoFilterLoader) {
- AutoLoad autoLoad = filter.getClass().getAnnotation(AutoLoad.class);
- if (autoLoad != null && autoLoad.value()) {
- filters.add(filter);
- }
- }
- autoFilters = filters;
- }
-
- for (Filter filter : autoFilters) {
- if (LOG.isInfoEnabled()) {
- LOG.info("load filter from spi :" + filter.getClass().getName());
- }
- addFilter(filter);
- }
- }
-
- private void initFromWrapDriverUrl() throws SQLException {
- if (!jdbcUrl.startsWith(DruidDriver.DEFAULT_PREFIX)) {
- return;
- }
-
- DataSourceProxyConfig config = DruidDriver.parseConfig(jdbcUrl, null);
- this.driverClass = config.getRawDriverClassName();
-
- LOG.error("error url : '" + jdbcUrl + "', it should be : '" + config.getRawUrl() + "'");
-
- this.jdbcUrl = config.getRawUrl();
- if (this.name == null) {
- this.name = config.getName();
- }
-
- for (Filter filter : config.getFilters()) {
- addFilter(filter);
- }
- }
-
- /**
- * 会去重复
- *
- * @param filter
- */
- private void addFilter(Filter filter) {
- boolean exists = false;
- for (Filter initedFilter : this.filters) {
- if (initedFilter.getClass() == filter.getClass()) {
- exists = true;
- break;
- }
- }
-
- if (!exists) {
- filter.init(this);
- this.filters.add(filter);
- }
-
- }
-
- private void validationQueryCheck() {
- if (!(testOnBorrow || testOnReturn || testWhileIdle)) {
- return;
- }
-
- if (this.validConnectionChecker != null) {
- return;
- }
-
- if (this.validationQuery != null && this.validationQuery.length() > 0) {
- return;
- }
-
- String errorMessage = "";
-
- if (testOnBorrow) {
- errorMessage += "testOnBorrow is true, ";
- }
-
- if (testOnReturn) {
- errorMessage += "testOnReturn is true, ";
- }
-
- if (testWhileIdle) {
- errorMessage += "testWhileIdle is true, ";
- }
-
- LOG.error(errorMessage + "validationQuery not set");
- }
-
- protected void initCheck() throws SQLException {
- if (JdbcUtils.ORACLE.equals(this.dbType)) {
- isOracle = true;
-
- if (driver.getMajorVersion() < 10) {
- throw new SQLException("not support oracle driver " + driver.getMajorVersion() + "."
- + driver.getMinorVersion());
- }
-
- if (driver.getMajorVersion() == 10 && isUseOracleImplicitCache()) {
- this.getConnectProperties().setProperty("oracle.jdbc.FreeMemoryOnEnterImplicitCache", "true");
- }
-
- oracleValidationQueryCheck();
- } else if (JdbcUtils.DB2.equals(dbType)) {
- db2ValidationQueryCheck();
- } else if (JdbcUtils.MYSQL.equals(this.dbType)
- || JdbcUtils.MYSQL_DRIVER_6.equals(this.dbType)) {
- isMySql = true;
- }
-
- if (removeAbandoned) {
- LOG.warn("removeAbandoned is true, not use in productiion.");
- }
- }
-
- private void oracleValidationQueryCheck() {
- if (validationQuery == null) {
- return;
- }
- if (validationQuery.length() == 0) {
- return;
- }
-
- SQLStatementParser sqlStmtParser = SQLParserUtils.createSQLStatementParser(validationQuery, this.dbType);
- List<SQLStatement> stmtList = sqlStmtParser.parseStatementList();
-
- if (stmtList.size() != 1) {
- return;
- }
-
- SQLStatement stmt = stmtList.get(0);
- if (!(stmt instanceof SQLSelectStatement)) {
- return;
- }
-
- SQLSelectQuery query = ((SQLSelectStatement) stmt).getSelect().getQuery();
- if (query instanceof SQLSelectQueryBlock) {
- if (((SQLSelectQueryBlock) query).getFrom() == null) {
- LOG.error("invalid oracle validationQuery. " + validationQuery + ", may should be : " + validationQuery
- + " FROM DUAL");
- }
- }
- }
-
- private void db2ValidationQueryCheck() {
- if (validationQuery == null) {
- return;
- }
- if (validationQuery.length() == 0) {
- return;
- }
-
- SQLStatementParser sqlStmtParser = SQLParserUtils.createSQLStatementParser(validationQuery, this.dbType);
- List<SQLStatement> stmtList = sqlStmtParser.parseStatementList();
-
- if (stmtList.size() != 1) {
- return;
- }
-
- SQLStatement stmt = stmtList.get(0);
- if (!(stmt instanceof SQLSelectStatement)) {
- return;
- }
-
- SQLSelectQuery query = ((SQLSelectStatement) stmt).getSelect().getQuery();
- if (query instanceof SQLSelectQueryBlock) {
- if (((SQLSelectQueryBlock) query).getFrom() == null) {
- LOG.error("invalid db2 validationQuery. " + validationQuery + ", may should be : " + validationQuery
- + " FROM SYSDUMMY");
- }
- }
- }
-
- private void initValidConnectionChecker() {
- if (this.validConnectionChecker != null) {
- return;
- }
-
- String realDriverClassName = driver.getClass().getName();
- if (JdbcUtils.isMySqlDriver(realDriverClassName)) {
- this.validConnectionChecker = new MySqlValidConnectionChecker();
-
- } else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER)
- || realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER2)) {
- this.validConnectionChecker = new OracleValidConnectionChecker();
-
- } else if (realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER)
- || realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_SQLJDBC4)
- || realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_JTDS)) {
- this.validConnectionChecker = new MSSQLValidConnectionChecker();
-
- } else if (realDriverClassName.equals(JdbcConstants.POSTGRESQL_DRIVER)
- || realDriverClassName.equals(JdbcConstants.ENTERPRISEDB_DRIVER)) {
- this.validConnectionChecker = new PGValidConnectionChecker();
- }
- }
-
- private void initExceptionSorter() {
- if (exceptionSorter instanceof NullExceptionSorter) {
- if (driver instanceof MockDriver) {
- return;
- }
- } else if (this.exceptionSorter != null) {
- return;
- }
-
-
- for (Class<?> driverClass = driver.getClass();;) {
- String realDriverClassName = driverClass.getName();
- if (realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER) //
- || realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER_6)) {
- this.exceptionSorter = new MySqlExceptionSorter();
- this.isMySql = true;
- } else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER)
- || realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER2)) {
- this.exceptionSorter = new OracleExceptionSorter();
- } else if (realDriverClassName.equals("com.informix.jdbc.IfxDriver")) {
- this.exceptionSorter = new InformixExceptionSorter();
-
- } else if (realDriverClassName.equals("com.sybase.jdbc2.jdbc.SybDriver")) {
- this.exceptionSorter = new SybaseExceptionSorter();
-
- } else if (realDriverClassName.equals(JdbcConstants.POSTGRESQL_DRIVER)
- || realDriverClassName.equals(JdbcConstants.ENTERPRISEDB_DRIVER)) {
- this.exceptionSorter = new PGExceptionSorter();
-
- } else if (realDriverClassName.equals("com.alibaba.druid.mock.MockDriver")) {
- this.exceptionSorter = new MockExceptionSorter();
- } else if (realDriverClassName.contains("DB2")) {
- this.exceptionSorter = new DB2ExceptionSorter();
-
- } else {
- Class<?> superClass = driverClass.getSuperclass();
- if (superClass != null && superClass != Object.class) {
- driverClass = superClass;
- continue;
- }
- }
-
- break;
- }
- }
-
- @Override
- public DruidPooledConnection getConnection() throws SQLException {
- return getConnection(maxWait);
- }
-
- public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
- init();
-
- if (filters.size() > 0) {
- FilterChainImpl filterChain = new FilterChainImpl(this);
- return filterChain.dataSource_connect(this, maxWaitMillis);
- } else {
- return getConnectionDirect(maxWaitMillis);
- }
- }
-
- @Override
- public PooledConnection getPooledConnection() throws SQLException {
- return getConnection(maxWait);
- }
-
- @Override
- public PooledConnection getPooledConnection(String user, String password) throws SQLException {
- throw new UnsupportedOperationException("Not supported by DruidDataSource");
- }
-
- public DruidPooledConnection getConnectionDirect(long maxWaitMillis) throws SQLException {
- int notFullTimeoutRetryCnt = 0;
- for (;;) {
- // handle notFullTimeoutRetry
- DruidPooledConnection poolableConnection;
- try {
- poolableConnection = getConnectionInternal(maxWaitMillis);
- } catch (GetConnectionTimeoutException ex) {
- if (notFullTimeoutRetryCnt <= this.notFullTimeoutRetryCount && !isFull()) {
- notFullTimeoutRetryCnt++;
- if (LOG.isWarnEnabled()) {
- LOG.warn("get connection timeout retry : " + notFullTimeoutRetryCnt);
- }
- continue;
- }
- throw ex;
- }
-
- if (testOnBorrow) {
- boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
- if (!validate) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("skip not validate connection.");
- }
-
- Connection realConnection = poolableConnection.conn;
- discardConnection(realConnection);
- continue;
- }
- } else {
- Connection realConnection = poolableConnection.conn;
- if (poolableConnection.conn.isClosed()) {
- discardConnection(null); // 传入null,避免重复关闭
- continue;
- }
-
- if (testWhileIdle) {
- final DruidConnectionHolder holder = poolableConnection.holder;
- long currentTimeMillis = System.currentTimeMillis();
- long lastActiveTimeMillis = holder.lastActiveTimeMillis;
- long lastKeepTimeMillis = holder.lastKeepTimeMillis;
-
- if (lastKeepTimeMillis > lastActiveTimeMillis) {
- lastActiveTimeMillis = lastKeepTimeMillis;
- }
-
- long idleMillis = currentTimeMillis - lastActiveTimeMillis;
-
- long timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis;
-
- if (timeBetweenEvictionRunsMillis <= 0) {
- timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
- }
-
- if (idleMillis >= timeBetweenEvictionRunsMillis
- || idleMillis < 0 // unexcepted branch
- ) {
- boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
- if (!validate) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("skip not validate connection.");
- }
-
- discardConnection(realConnection);
- continue;
- }
- }
- }
- }
-
- if (removeAbandoned) {
- StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
- poolableConnection.connectStackTrace = stackTrace;
- poolableConnection.setConnectedTimeNano();
- poolableConnection.traceEnable = true;
-
- activeConnectionLock.lock();
- try {
- activeConnections.put(poolableConnection, PRESENT);
- } finally {
- activeConnectionLock.unlock();
- }
- }
-
- if (!this.defaultAutoCommit) {
- poolableConnection.setAutoCommit(false);
- }
-
- return poolableConnection;
- }
- }
-
- /**
- * 抛弃连接,不进行回收,而是抛弃
- *
- * @param realConnection
- */
- public void discardConnection(Connection realConnection) {
- JdbcUtils.close(realConnection);
-
- lock.lock();
- try {
- activeCount--;
- discardCount++;
-
- if (activeCount <= minIdle) {
- emptySignal();
- }
- } finally {
- lock.unlock();
- }
- }
-
- private DruidPooledConnection getConnectionInternal(long maxWait) throws SQLException {
- if (closed) {
- connectErrorCountUpdater.incrementAndGet(this);
- throw new DataSourceClosedException("dataSource already closed at " + new Date(closeTimeMillis));
- }
-
- if (!enable) {
- connectErrorCountUpdater.incrementAndGet(this);
- throw new DataSourceDisableException();
- }
-
- final long nanos = TimeUnit.MILLISECONDS.toNanos(maxWait);
- final int maxWaitThreadCount = this.maxWaitThreadCount;
-
- DruidConnectionHolder holder;
-
- for (boolean createDirect = false;;) {
- if (createDirect) {
- createStartNanosUpdater.set(this, System.nanoTime());
- if (creatingCountUpdater.compareAndSet(this, 0, 1)) {
- PhysicalConnectionInfo pyConnInfo = DruidDataSource.this.createPhysicalConnection();
- holder = new DruidConnectionHolder(this, pyConnInfo);
- holder.lastActiveTimeMillis = System.currentTimeMillis();
-
- creatingCountUpdater.decrementAndGet(this);
- directCreateCountUpdater.incrementAndGet(this);
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("conn-direct_create ");
- }
-
- boolean discard = false;
- lock.lock();
- try {
- if (activeCount < maxActive) {
- activeCount++;
- if (activeCount > activePeak) {
- activePeak = activeCount;
- activePeakTime = System.currentTimeMillis();
- }
- break;
- } else {
- discard = true;
- }
- } finally {
- lock.unlock();
- }
-
- if (discard) {
- JdbcUtils.close(pyConnInfo.getPhysicalConnection());
- }
- }
- }
-
- try {
- lock.lockInterruptibly();
- } catch (InterruptedException e) {
- connectErrorCountUpdater.incrementAndGet(this);
- throw new SQLException("interrupt", e);
- }
-
- try {
- if (maxWaitThreadCount > 0
- && notEmptyWaitThreadCount >= maxWaitThreadCount) {
- connectErrorCountUpdater.incrementAndGet(this);
- throw new SQLException("maxWaitThreadCount " + maxWaitThreadCount + ", current wait Thread count "
- + lock.getQueueLength());
- }
-
- if (onFatalError
- && onFatalErrorMaxActive > 0
- && activeCount >= onFatalErrorMaxActive) {
- connectErrorCountUpdater.incrementAndGet(this);
-
- StringBuilder errorMsg = new StringBuilder();
- errorMsg.append("onFatalError, activeCount ")
- .append(activeCount)
- .append(", onFatalErrorMaxActive ")
- .append(onFatalErrorMaxActive);
-
- if (lastFatalErrorTimeMillis > 0) {
- errorMsg.append(", time '")
- .append(StringUtils.formatDateTime19(
- lastFatalErrorTimeMillis, TimeZone.getDefault()))
- .append("'");
- }
-
- if (lastFatalErrorSql != null) {
- errorMsg.append(", sql \n")
- .append(lastFatalErrorSql);
- }
-
- throw new SQLException(
- errorMsg.toString(), lastFatalError);
- }
-
- connectCount++;
-
- if (createScheduler != null
- && poolingCount == 0
- && activeCount < maxActive
- && creatingCountUpdater.get(this) == 0
- && createScheduler instanceof ScheduledThreadPoolExecutor) {
- ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) createScheduler;
- if (executor.getQueue().size() > 0) {
- createDirect = true;
- continue;
- }
- }
-
- if (maxWait > 0) {
- holder = pollLast(nanos);
- } else {
- holder = takeLast();
- }
-
- if (holder != null) {
- activeCount++;
- if (activeCount > activePeak) {
- activePeak = activeCount;
- activePeakTime = System.currentTimeMillis();
- }
- }
- } catch (InterruptedException e) {
- connectErrorCountUpdater.incrementAndGet(this);
- throw new SQLException(e.getMessage(), e);
- } catch (SQLException e) {
- connectErrorCountUpdater.incrementAndGet(this);
- throw e;
- } finally {
- lock.unlock();
- }
-
- break;
- }
-
- if (holder == null) {
- long waitNanos = waitNanosLocal.get();
-
- StringBuilder buf = new StringBuilder(128);
- buf.append("wait millis ")//
- .append(waitNanos / (1000 * 1000))//
- .append(", active ").append(activeCount)//
- .append(", maxActive ").append(maxActive)//
- .append(", creating ").append(creatingCount)//
- ;
- if (creatingCount > 0 && createStartNanos > 0) {
- long createElapseMillis = (System.nanoTime() - createStartNanos) / (1000 * 1000);
- if (createElapseMillis > 0) {
- buf.append(", createElapseMillis ").append(createElapseMillis);
- }
- }
-
- if (createErrorCount > 0) {
- buf.append(", createErrorCount ").append(createErrorCount);
- }
-
- List<JdbcSqlStatValue> sqlList = this.getDataSourceStat().getRuningSqlList();
- for (int i = 0; i < sqlList.size(); ++i) {
- if (i != 0) {
- buf.append('\n');
- } else {
- buf.append(", ");
- }
- JdbcSqlStatValue sql = sqlList.get(i);
- buf.append("runningSqlCount ").append(sql.getRunningCount());
- buf.append(" : ");
- buf.append(sql.getSql());
- }
-
- String errorMessage = buf.toString();
-
- if (this.createError != null) {
- throw new GetConnectionTimeoutException(errorMessage, createError);
- } else {
- throw new GetConnectionTimeoutException(errorMessage);
- }
- }
-
- holder.incrementUseCount();
-
- DruidPooledConnection poolalbeConnection = new DruidPooledConnection(holder);
- return poolalbeConnection;
- }
-
- public void handleConnectionException(DruidPooledConnection pooledConnection, Throwable t, String sql) throws SQLException {
- final DruidConnectionHolder holder = pooledConnection.getConnectionHolder();
-
- errorCountUpdater.incrementAndGet(this);
- lastError = t;
- lastErrorTimeMillis = System.currentTimeMillis();
-
- 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 (exceptionSorter != null && exceptionSorter.isExceptionFatal(sqlEx)) {
- handleFatalError(pooledConnection, sqlEx, sql);
- }
-
- throw sqlEx;
- } else {
- throw new SQLException("Error", t);
- }
- }
-
- protected final void handleFatalError(DruidPooledConnection conn, SQLException error, String sql) throws SQLException {
- final DruidConnectionHolder holder = conn.holder;
-
- if (conn.isTraceEnable()) {
- activeConnectionLock.lock();
- try {
- if (conn.isTraceEnable()) {
- activeConnections.remove(conn);
- conn.setTraceEnable(false);
- }
- } finally {
- activeConnectionLock.unlock();
- }
- }
-
- long lastErrorTimeMillis = this.lastErrorTimeMillis;
- if (lastErrorTimeMillis == 0) {
- lastErrorTimeMillis = System.currentTimeMillis();
- }
-
- if (sql != null && sql.length() > 1024) {
- sql = sql.substring(0, 1024);
- }
-
- boolean requireDiscard = false;
- final ReentrantLock lock = conn.lock;
- lock.lock();
- try {
- if ((!conn.isClosed()) || !conn.isDisable()) {
- holder.setDiscard(true);
- conn.disable(error);
- requireDiscard = true;
- }
-
- lastFatalErrorTimeMillis = lastErrorTimeMillis;
- onFatalError = true;
- lastFatalError = error;
- lastFatalErrorSql = sql;
- } finally {
- lock.unlock();
- }
-
- if (requireDiscard) {
- if (holder.statementTrace != null) {
- holder.lock.lock();
- try {
- for (Statement stmt : holder.statementTrace) {
- JdbcUtils.close(stmt);
- }
- } finally {
- holder.lock.unlock();
- }
- }
-
- this.discardConnection(holder.getConnection());
- holder.setDiscard(true);
- }
-
- LOG.error("discard connection", error);
- }
-
- /**
- * 回收连接
- */
- protected void recycle(DruidPooledConnection pooledConnection) throws SQLException {
- final DruidConnectionHolder holder = pooledConnection.holder;
-
- if (holder == null) {
- LOG.warn("connectionHolder is null");
- return;
- }
-
- if (logDifferentThread //
- && (!isAsyncCloseConnectionEnable()) //
- && pooledConnection.ownerThread != Thread.currentThread()//
- ) {
- LOG.warn("get/close not same thread");
- }
-
- final Connection physicalConnection = holder.conn;
-
- if (pooledConnection.traceEnable) {
- Object oldInfo = null;
- activeConnectionLock.lock();
- try {
- if (pooledConnection.traceEnable) {
- oldInfo = activeConnections.remove(pooledConnection);
- pooledConnection.traceEnable = false;
- }
- } finally {
- activeConnectionLock.unlock();
- }
- if (oldInfo == null) {
- if (LOG.isWarnEnabled()) {
- LOG.warn("remove abandonded failed. activeConnections.size " + activeConnections.size());
- }
- }
- }
-
- final boolean isAutoCommit = holder.underlyingAutoCommit;
- final boolean isReadOnly = holder.underlyingReadOnly;
- final boolean testOnReturn = this.testOnReturn;
-
- try {
- // check need to rollback?
- if ((!isAutoCommit) && (!isReadOnly)) {
- pooledConnection.rollback();
- }
-
- // reset holder, restore default settings, clear warnings
- boolean isSameThread = pooledConnection.ownerThread == Thread.currentThread();
- if (!isSameThread) {
- final ReentrantLock lock = pooledConnection.lock;
- lock.lock();
- try {
- holder.reset();
- } finally {
- lock.unlock();
- }
- } else {
- holder.reset();
- }
-
- if (holder.discard) {
- return;
- }
-
- if (phyMaxUseCount > 0 && holder.useCount >= phyMaxUseCount) {
- discardConnection(holder.conn);
- return;
- }
-
- if (physicalConnection.isClosed()) {
- lock.lock();
- try {
- activeCount--;
- closeCount++;
- } finally {
- lock.unlock();
- }
- return;
- }
-
- if (testOnReturn) {
- boolean validate = testConnectionInternal(holder, physicalConnection);
- if (!validate) {
- JdbcUtils.close(physicalConnection);
-
- destroyCountUpdater.incrementAndGet(this);
-
- lock.lock();
- try {
- activeCount--;
- closeCount++;
- } finally {
- lock.unlock();
- }
- return;
- }
- }
-
- if (!enable) {
- discardConnection(holder.conn);
- return;
- }
-
- boolean result;
- final long currentTimeMillis = System.currentTimeMillis();
-
- if (phyTimeoutMillis > 0) {
- long phyConnectTimeMillis = currentTimeMillis - holder.connectTimeMillis;
- if (phyConnectTimeMillis > phyTimeoutMillis) {
- discardConnection(holder.conn);
- return;
- }
- }
-
- lock.lock();
- try {
- activeCount--;
- closeCount++;
-
- result = putLast(holder, currentTimeMillis);
- recycleCount++;
- } finally {
- lock.unlock();
- }
-
- if (!result) {
- JdbcUtils.close(holder.conn);
- LOG.info("connection recyle failed.");
- }
- } catch (Throwable e) {
- holder.clearStatementCache();
-
- if (!holder.discard) {
- this.discardConnection(physicalConnection);
- holder.discard = true;
- }
-
- LOG.error("recyle error", e);
- recycleErrorCountUpdater.incrementAndGet(this);
- }
- }
-
- public long getRecycleErrorCount() {
- return recycleErrorCount;
- }
-
- public void clearStatementCache() throws SQLException {
- lock.lock();
- try {
- for (int i = 0; i < poolingCount; ++i) {
- DruidConnectionHolder conn = connections[i];
-
- if (conn.statementPool != null) {
- conn.statementPool.clear();
- }
- }
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * close datasource
- */
- public void close() {
- if (LOG.isInfoEnabled()) {
- LOG.info("{dataSource-" + this.getID() + "} closing ...");
- }
-
- lock.lock();
- try {
- if (this.closed) {
- return;
- }
-
- if (!this.inited) {
- return;
- }
-
- this.closing = true;
-
- if (logStatsThread != null) {
- logStatsThread.interrupt();
- }
-
- if (createConnectionThread != null) {
- createConnectionThread.interrupt();
- }
-
- if (destroyConnectionThread != null) {
- destroyConnectionThread.interrupt();
- }
-
- if (createSchedulerFuture != null) {
- createSchedulerFuture.cancel(true);
- }
-
- if (destroySchedulerFuture != null) {
- destroySchedulerFuture.cancel(true);
- }
-
- for (int i = 0; i < poolingCount; ++i) {
- DruidConnectionHolder connHolder = connections[i];
-
- for (PreparedStatementHolder stmtHolder : connHolder.getStatementPool().getMap().values()) {
- connHolder.getStatementPool().closeRemovedStatement(stmtHolder);
- }
- connHolder.getStatementPool().getMap().clear();
-
- Connection physicalConnection = connHolder.getConnection();
- try {
- physicalConnection.close();
- } catch (Exception ex) {
- LOG.warn("close connection error", ex);
- }
- connections[i] = null;
- destroyCountUpdater.incrementAndGet(this);
- }
- poolingCount = 0;
- unregisterMbean();
-
- enable = false;
- notEmpty.signalAll();
- notEmptySignalCount++;
-
- this.closed = true;
- this.closeTimeMillis = System.currentTimeMillis();
-
- for (Filter filter : filters) {
- filter.destroy();
- }
- } finally {
- lock.unlock();
- }
-
- if (LOG.isInfoEnabled()) {
- LOG.info("{dataSource-" + this.getID() + "} closed");
- }
- }
-
- public void registerMbean() {
- if (!mbeanRegistered) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
-
- @Override
- public Object run() {
- ObjectName objectName = DruidDataSourceStatManager.addDataSource(DruidDataSource.this,
- DruidDataSource.this.name);
-
- DruidDataSource.this.setObjectName(objectName);
- DruidDataSource.this.mbeanRegistered = true;
-
- return null;
- }
- });
- }
- }
-
- public void unregisterMbean() {
- if (mbeanRegistered) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
-
- @Override
- public Object run() {
- DruidDataSourceStatManager.removeDataSource(DruidDataSource.this);
- DruidDataSource.this.mbeanRegistered = false;
- return null;
- }
- });
- }
- }
-
- public boolean isMbeanRegistered() {
- return mbeanRegistered;
- }
-
- boolean putLast(DruidConnectionHolder e, long lastActiveTimeMillis) {
- if (poolingCount >= maxActive) {
- return false;
- }
-
- e.lastActiveTimeMillis = lastActiveTimeMillis;
- connections[poolingCount] = e;
- incrementPoolingCount();
-
- if (poolingCount > poolingPeak) {
- poolingPeak = poolingCount;
- poolingPeakTime = lastActiveTimeMillis;
- }
-
- notEmpty.signal();
- notEmptySignalCount++;
-
- return true;
- }
-
- DruidConnectionHolder takeLast() throws InterruptedException, SQLException {
- try {
- while (poolingCount == 0) {
- emptySignal(); // send signal to CreateThread create connection
-
- if (failFast && isFailContinuous()) {
- throw new DataSourceNotAvailableException(createError);
- }
-
- notEmptyWaitThreadCount++;
- if (notEmptyWaitThreadCount > notEmptyWaitThreadPeak) {
- notEmptyWaitThreadPeak = notEmptyWaitThreadCount;
- }
- try {
- notEmpty.await(); // signal by recycle or creator
- } finally {
- notEmptyWaitThreadCount--;
- }
- notEmptyWaitCount++;
-
- if (!enable) {
- connectErrorCountUpdater.incrementAndGet(this);
- throw new DataSourceDisableException();
- }
- }
- } catch (InterruptedException ie) {
- notEmpty.signal(); // propagate to non-interrupted thread
- notEmptySignalCount++;
- throw ie;
- }
-
- decrementPoolingCount();
- DruidConnectionHolder last = connections[poolingCount];
- connections[poolingCount] = null;
-
- return last;
- }
-
- private DruidConnectionHolder pollLast(long nanos) throws InterruptedException, SQLException {
- long estimate = nanos;
-
- for (;;) {
- if (poolingCount == 0) {
- emptySignal(); // send signal to CreateThread create connection
-
- if (failFast && isFailContinuous()) {
- throw new DataSourceNotAvailableException(createError);
- }
-
- if (estimate <= 0) {
- waitNanosLocal.set(nanos - estimate);
- return null;
- }
-
- notEmptyWaitThreadCount++;
- if (notEmptyWaitThreadCount > notEmptyWaitThreadPeak) {
- notEmptyWaitThreadPeak = notEmptyWaitThreadCount;
- }
-
- try {
- long startEstimate = estimate;
- estimate = notEmpty.awaitNanos(estimate); // signal by
- // recycle or
- // creator
- notEmptyWaitCount++;
- notEmptyWaitNanos += (startEstimate - estimate);
-
- if (!enable) {
- connectErrorCountUpdater.incrementAndGet(this);
- throw new DataSourceDisableException();
- }
- } catch (InterruptedException ie) {
- notEmpty.signal(); // propagate to non-interrupted thread
- notEmptySignalCount++;
- throw ie;
- } finally {
- notEmptyWaitThreadCount--;
- }
-
- if (poolingCount == 0) {
- if (estimate > 0) {
- continue;
- }
-
- waitNanosLocal.set(nanos - estimate);
- return null;
- }
- }
-
- decrementPoolingCount();
- DruidConnectionHolder last = connections[poolingCount];
- connections[poolingCount] = null;
-
- long waitNanos = nanos - estimate;
- last.setLastNotEmptyWaitNanos(waitNanos);
-
- return last;
- }
- }
-
- private final void decrementPoolingCount() {
- poolingCount--;
- }
-
- private final void incrementPoolingCount() {
- poolingCount++;
- }
-
- @Override
- public Connection getConnection(String username, String password) throws SQLException {
- if (this.username == null
- && this.password == null
- && username != null
- && password != null) {
- this.username = username;
- this.password = password;
-
- return getConnection();
- }
-
- if (!StringUtils.equals(username, this.username)) {
- throw new UnsupportedOperationException("Not supported by DruidDataSource");
- }
-
- if (!StringUtils.equals(password, this.password)) {
- throw new UnsupportedOperationException("Not supported by DruidDataSource");
- }
-
- return getConnection();
- }
-
- public long getCreateCount() {
- return createCount;
- }
-
- public long getDestroyCount() {
- return destroyCount;
- }
-
- public long getConnectCount() {
- lock.lock();
- try {
- return connectCount;
- } finally {
- lock.unlock();
- }
- }
-
- public long getCloseCount() {
- return closeCount;
- }
-
- public long getConnectErrorCount() {
- return connectErrorCountUpdater.get(this);
- }
-
- @Override
- public int getPoolingCount() {
- lock.lock();
- try {
- return poolingCount;
- } finally {
- lock.unlock();
- }
- }
-
- public int getPoolingPeak() {
- lock.lock();
- try {
- return poolingPeak;
- } finally {
- lock.unlock();
- }
- }
-
- public Date getPoolingPeakTime() {
- if (poolingPeakTime <= 0) {
- return null;
- }
-
- return new Date(poolingPeakTime);
- }
-
- public long getRecycleCount() {
- return recycleCount;
- }
-
- public int getActiveCount() {
- lock.lock();
- try {
- return activeCount;
- } finally {
- lock.unlock();
- }
- }
-
- public void logStats() {
- final DruidDataSourceStatLogger statLogger = this.statLogger;
- if (statLogger == null) {
- return;
- }
-
- DruidDataSourceStatValue statValue = getStatValueAndReset();
-
- statLogger.log(statValue);
- }
-
- public DruidDataSourceStatValue getStatValueAndReset() {
- DruidDataSourceStatValue value = new DruidDataSourceStatValue();
-
- lock.lock();
- try {
- value.setPoolingCount(this.poolingCount);
- value.setPoolingPeak(this.poolingPeak);
- value.setPoolingPeakTime(this.poolingPeakTime);
-
- value.setActiveCount(this.activeCount);
- value.setActivePeak(this.activePeak);
- value.setActivePeakTime(this.activePeakTime);
-
- value.setConnectCount(this.connectCount);
- value.setCloseCount(this.closeCount);
- value.setWaitThreadCount(lock.getWaitQueueLength(notEmpty));
- value.setNotEmptyWaitCount(this.notEmptyWaitCount);
- value.setNotEmptyWaitNanos(this.notEmptyWaitNanos);
- value.setKeepAliveCheckCount(this.keepAliveCheckCount);
-
- // reset
- this.poolingPeak = 0;
- this.poolingPeakTime = 0;
- this.activePeak = 0;
- this.activePeakTime = 0;
- this.connectCount = 0;
- this.closeCount = 0;
- this.keepAliveCheckCount = 0;
-
- this.notEmptyWaitCount = 0;
- this.notEmptyWaitNanos = 0;
- } finally {
- lock.unlock();
- }
-
- value.setName(this.getName());
- value.setDbType(this.dbType);
- value.setDriverClassName(this.getDriverClassName());
-
- value.setUrl(this.getUrl());
- value.setUserName(this.getUsername());
- value.setFilterClassNames(this.getFilterClassNames());
-
- value.setInitialSize(this.getInitialSize());
- value.setMinIdle(this.getMinIdle());
- value.setMaxActive(this.getMaxActive());
-
- value.setQueryTimeout(this.getQueryTimeout());
- value.setTransactionQueryTimeout(this.getTransactionQueryTimeout());
- value.setLoginTimeout(this.getLoginTimeout());
- value.setValidConnectionCheckerClassName(this.getValidConnectionCheckerClassName());
- value.setExceptionSorterClassName(this.getExceptionSorterClassName());
-
- value.setTestOnBorrow(this.testOnBorrow);
- value.setTestOnReturn(this.testOnReturn);
- value.setTestWhileIdle(this.testWhileIdle);
-
- value.setDefaultAutoCommit(this.isDefaultAutoCommit());
-
- if (defaultReadOnly != null) {
- value.setDefaultReadOnly(defaultReadOnly);
- }
- value.setDefaultTransactionIsolation(this.getDefaultTransactionIsolation());
-
- value.setLogicConnectErrorCount(connectErrorCountUpdater.getAndSet(this, 0));
-
- value.setPhysicalConnectCount(createCountUpdater.getAndSet(this, 0));
- value.setPhysicalCloseCount(destroyCountUpdater.getAndSet(this, 0));
- value.setPhysicalConnectErrorCount(createErrorCountUpdater.getAndSet(this, 0));
-
- value.setExecuteCount(this.getAndResetExecuteCount());
- value.setErrorCount(errorCountUpdater.getAndSet(this, 0));
- value.setCommitCount(commitCountUpdater.getAndSet(this, 0));
- value.setRollbackCount(rollbackCountUpdater.getAndSet(this, 0));
-
- value.setPstmtCacheHitCount(cachedPreparedStatementHitCountUpdater.getAndSet(this,0));
- value.setPstmtCacheMissCount(cachedPreparedStatementMissCountUpdater.getAndSet(this, 0));
-
- value.setStartTransactionCount(startTransactionCountUpdater.getAndSet(this, 0));
- value.setTransactionHistogram(this.getTransactionHistogram().toArrayAndReset());
-
- value.setConnectionHoldTimeHistogram(this.getDataSourceStat().getConnectionHoldHistogram().toArrayAndReset());
- value.setRemoveAbandoned(this.isRemoveAbandoned());
- value.setClobOpenCount(this.getDataSourceStat().getClobOpenCountAndReset());
- value.setBlobOpenCount(this.getDataSourceStat().getBlobOpenCountAndReset());
-
- value.setSqlSkipCount(this.getDataSourceStat().getSkipSqlCountAndReset());
- value.setSqlList(this.getDataSourceStat().getSqlStatMapAndReset());
-
- return value;
- }
-
- public long getRemoveAbandonedCount() {
- return removeAbandonedCount;
- }
-
- protected boolean put(PhysicalConnectionInfo physicalConnectionInfo) {
- DruidConnectionHolder holder = null;
- try {
- holder = new DruidConnectionHolder(DruidDataSource.this, physicalConnectionInfo);
- } catch (SQLException ex) {
- lock.lock();
- try {
- if (createScheduler != null) {
- createTaskCount--;
- }
- } finally {
- lock.unlock();
- }
- LOG.error("create connection holder error", ex);
- return false;
- }
-
- return put(holder);
- }
-
- private boolean put(DruidConnectionHolder holder) {
- lock.lock();
- try {
- if (poolingCount >= maxActive) {
- return false;
- }
- connections[poolingCount] = holder;
- incrementPoolingCount();
-
- if (poolingCount > poolingPeak) {
- poolingPeak = poolingCount;
- poolingPeakTime = System.currentTimeMillis();
- }
-
- notEmpty.signal();
- notEmptySignalCount++;
-
- if (createScheduler != null) {
- createTaskCount--;
-
- if (poolingCount + createTaskCount < notEmptyWaitThreadCount //
- && activeCount + poolingCount + createTaskCount < maxActive) {
- emptySignal();
- }
- }
- } finally {
- lock.unlock();
- }
- return true;
- }
-
- public class CreateConnectionTask implements Runnable {
-
- private int errorCount = 0;
- private boolean initTask = false;
-
- public CreateConnectionTask() {
-
- }
-
- public CreateConnectionTask(boolean initTask) {
- this.initTask = initTask;
- }
-
- @Override
- public void run() {
- runInternal();
- }
-
- private void runInternal() {
- for (;;) {
-
- // addLast
- lock.lock();
- try {
- if (closed || closing) {
- createTaskCount--;
- return;
- }
-
- boolean emptyWait = true;
-
- if (createError != null && poolingCount == 0) {
- emptyWait = false;
- }
-
- if (emptyWait) {
- // 必须存在线程等待,才创建连接
- if (poolingCount >= notEmptyWaitThreadCount //
- && (!(keepAlive && activeCount + poolingCount < minIdle))
- && (!initTask)
- && !isFailContinuous()
- ) {
- createTaskCount--;
- return;
- }
-
- // 防止创建超过maxActive数量的连接
- if (activeCount + poolingCount >= maxActive) {
- createTaskCount--;
- return;
- }
- }
- } finally {
- lock.unlock();
- }
-
- PhysicalConnectionInfo physicalConnection = null;
-
- try {
- physicalConnection = createPhysicalConnection();
- } catch (OutOfMemoryError e) {
- LOG.error("create connection OutOfMemoryError, out memory. ", e);
-
- errorCount++;
- if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) {
- // fail over retry attempts
- setFailContinuous(true);
- if (failFast) {
- lock.lock();
- try {
- notEmpty.signalAll();
- } finally {
- lock.unlock();
- }
- }
-
- if (breakAfterAcquireFailure) {
- lock.lock();
- try {
- createTaskCount--;
- } finally {
- lock.unlock();
- }
- return;
- }
-
- this.errorCount = 0; // reset errorCount
- if (closing || closed) {
- createTaskCount--;
- return;
- }
- createSchedulerFuture = createScheduler.schedule(this, timeBetweenConnectErrorMillis, TimeUnit.MILLISECONDS);
- return;
- }
- } catch (SQLException e) {
- LOG.error("create connection SQLException, url: " + jdbcUrl, e);
-
- errorCount++;
- if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) {
- // fail over retry attempts
- setFailContinuous(true);
- if (failFast) {
- lock.lock();
- try {
- notEmpty.signalAll();
- } finally {
- lock.unlock();
- }
- }
-
- if (breakAfterAcquireFailure) {
- lock.lock();
- try {
- createTaskCount--;
- } finally {
- lock.unlock();
- }
- return;
- }
-
- this.errorCount = 0; // reset errorCount
- if (closing || closed) {
- createTaskCount--;
- return;
- }
- createSchedulerFuture = createScheduler.schedule(this, timeBetweenConnectErrorMillis, TimeUnit.MILLISECONDS);
- return;
- }
- } catch (RuntimeException e) {
- LOG.error("create connection RuntimeException", e);
- // unknow fatal exception
- setFailContinuous(true);
- continue;
- } catch (Error e) {
- lock.lock();
- try {
- createTaskCount--;
- } finally {
- lock.unlock();
- }
- LOG.error("create connection Error", e);
- // unknow fatal exception
- setFailContinuous(true);
- break;
- } catch (Throwable e) {
- LOG.error("create connection unexecpted error.", e);
- break;
- }
-
- if (physicalConnection == null) {
- continue;
- }
-
- boolean result = put(physicalConnection);
- if (!result) {
- JdbcUtils.close(physicalConnection.getPhysicalConnection());
- LOG.info("put physical connection to pool failed.");
- }
- break;
- }
- }
- }
-
- public class CreateConnectionThread extends Thread {
-
- public CreateConnectionThread(String name){
- super(name);
- this.setDaemon(true);
- }
-
- public void run() {
- initedLatch.countDown();
-
- long lastDiscardCount = 0;
- int errorCount = 0;
- for (;;) {
- // addLast
- try {
- lock.lockInterruptibly();
- } catch (InterruptedException e2) {
- break;
- }
-
- long discardCount = DruidDataSource.this.discardCount;
- boolean discardChanged = discardCount - lastDiscardCount > 0;
- lastDiscardCount = discardCount;
-
- try {
- boolean emptyWait = true;
-
- if (createError != null
- && poolingCount == 0
- && !discardChanged) {
- emptyWait = false;
- }
-
- if (emptyWait
- && asyncInit && createCount < initialSize) {
- emptyWait = false;
- }
-
- if (emptyWait) {
- // 必须存在线程等待,才创建连接
- if (poolingCount >= notEmptyWaitThreadCount //
- && (!(keepAlive && activeCount + poolingCount < minIdle))
- && !isFailContinuous()
- ) {
- empty.await();
- }
-
- // 防止创建超过maxActive数量的连接
- if (activeCount + poolingCount >= maxActive) {
- empty.await();
- continue;
- }
- }
-
- } catch (InterruptedException e) {
- lastCreateError = e;
- lastErrorTimeMillis = System.currentTimeMillis();
-
- if (!closing) {
- LOG.error("create connection Thread Interrupted, url: " + jdbcUrl, e);
- }
- break;
- } finally {
- lock.unlock();
- }
-
- PhysicalConnectionInfo connection = null;
-
- try {
- connection = createPhysicalConnection();
- } catch (SQLException e) {
- LOG.error("create connection SQLException, url: " + jdbcUrl + ", errorCode " + e.getErrorCode()
- + ", state " + e.getSQLState(), e);
-
- errorCount++;
- if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) {
- // fail over retry attempts
- setFailContinuous(true);
- if (failFast) {
- lock.lock();
- try {
- notEmpty.signalAll();
- } finally {
- lock.unlock();
- }
- }
-
- if (breakAfterAcquireFailure) {
- break;
- }
-
- try {
- Thread.sleep(timeBetweenConnectErrorMillis);
- } catch (InterruptedException interruptEx) {
- break;
- }
- }
- } catch (RuntimeException e) {
- LOG.error("create connection RuntimeException", e);
- setFailContinuous(true);
- continue;
- } catch (Error e) {
- LOG.error("create connection Error", e);
- setFailContinuous(true);
- break;
- }
-
- if (connection == null) {
- continue;
- }
-
- boolean result = put(connection);
- if (!result) {
- JdbcUtils.close(connection.getPhysicalConnection());
- LOG.info("put physical connection to pool failed.");
- }
-
- errorCount = 0; // reset errorCount
- }
- }
- }
-
- public class DestroyConnectionThread extends Thread {
-
- public DestroyConnectionThread(String name){
- super(name);
- this.setDaemon(true);
- }
-
- public void run() {
- initedLatch.countDown();
-
- for (;;) {
- // 从前面开始删除
- try {
- if (closed) {
- break;
- }
-
- if (timeBetweenEvictionRunsMillis > 0) {
- Thread.sleep(timeBetweenEvictionRunsMillis);
- } else {
- Thread.sleep(1000); //
- }
-
- if (Thread.interrupted()) {
- break;
- }
-
- destroyTask.run();
- } catch (InterruptedException e) {
- break;
- }
- }
- }
-
- }
-
- public class DestroyTask implements Runnable {
- public DestroyTask() {
-
- }
-
- @Override
- public void run() {
- shrink(true, keepAlive);
-
- if (isRemoveAbandoned()) {
- removeAbandoned();
- }
- }
-
- }
-
- public class LogStatsThread extends Thread {
-
- public LogStatsThread(String name){
- super(name);
- this.setDaemon(true);
- }
-
- public void run() {
- try {
- for (;;) {
- try {
- logStats();
- } catch (Exception e) {
- LOG.error("logStats error", e);
- }
-
- Thread.sleep(timeBetweenLogStatsMillis);
- }
- } catch (InterruptedException e) {
- // skip
- }
- }
- }
-
- public int removeAbandoned() {
- int removeCount = 0;
-
- long currrentNanos = System.nanoTime();
-
- List<DruidPooledConnection> abandonedList = new ArrayList<DruidPooledConnection>();
-
- activeConnectionLock.lock();
- try {
- Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator();
-
- for (; iter.hasNext();) {
- DruidPooledConnection pooledConnection = iter.next();
-
- if (pooledConnection.isRunning()) {
- continue;
- }
-
- long timeMillis = (currrentNanos - pooledConnection.getConnectedTimeNano()) / (1000 * 1000);
-
- if (timeMillis >= removeAbandonedTimeoutMillis) {
- iter.remove();
- pooledConnection.setTraceEnable(false);
- abandonedList.add(pooledConnection);
- }
- }
- } finally {
- activeConnectionLock.unlock();
- }
-
- if (abandonedList.size() > 0) {
- for (DruidPooledConnection pooledConnection : abandonedList) {
- final ReentrantLock lock = pooledConnection.lock;
- lock.lock();
- try {
- if (pooledConnection.isDisable()) {
- continue;
- }
- } finally {
- lock.unlock();
- }
-
- JdbcUtils.close(pooledConnection);
- pooledConnection.abandond();
- removeAbandonedCount++;
- removeCount++;
-
- if (isLogAbandoned()) {
- StringBuilder buf = new StringBuilder();
- buf.append("abandon connection, owner thread: ");
- buf.append(pooledConnection.getOwnerThread().getName());
- buf.append(", connected at : ");
- buf.append(pooledConnection.getConnectedTimeMillis());
- buf.append(", open stackTrace\n");
-
- StackTraceElement[] trace = pooledConnection.getConnectStackTrace();
- for (int i = 0; i < trace.length; i++) {
- buf.append("\tat ");
- buf.append(trace[i].toString());
- buf.append("\n");
- }
-
- buf.append("ownerThread current state is " + pooledConnection.getOwnerThread().getState()
- + ", current stackTrace\n");
- trace = pooledConnection.getOwnerThread().getStackTrace();
- for (int i = 0; i < trace.length; i++) {
- buf.append("\tat ");
- buf.append(trace[i].toString());
- buf.append("\n");
- }
-
- LOG.error(buf.toString());
- }
- }
- }
-
- return removeCount;
- }
-
- /** Instance key */
- protected String instanceKey = null;
-
- public Reference getReference() throws NamingException {
- final String className = getClass().getName();
- final String factoryName = className + "Factory"; // XXX: not robust
- Reference ref = new Reference(className, factoryName, null);
- ref.add(new StringRefAddr("instanceKey", instanceKey));
- ref.add(new StringRefAddr("url", this.getUrl()));
- ref.add(new StringRefAddr("username", this.getUsername()));
- ref.add(new StringRefAddr("password", this.getPassword()));
- // TODO ADD OTHER PROPERTIES
- return ref;
- }
-
- @Override
- public List<String> getFilterClassNames() {
- List<String> names = new ArrayList<String>();
- for (Filter filter : filters) {
- names.add(filter.getClass().getName());
- }
- return names;
- }
-
- public int getRawDriverMajorVersion() {
- int version = -1;
- if (this.driver != null) {
- version = driver.getMajorVersion();
- }
- return version;
- }
-
- public int getRawDriverMinorVersion() {
- int version = -1;
- if (this.driver != null) {
- version = driver.getMinorVersion();
- }
- return version;
- }
-
- public String getProperties() {
- Properties properties = new Properties();
- properties.putAll(connectProperties);
- if (properties.containsKey("password")) {
- properties.put("password", "******");
- }
- return properties.toString();
- }
-
- @Override
- public void shrink() {
- shrink(false, false);
- }
-
- public void shrink(boolean checkTime) {
- shrink(checkTime, keepAlive);
- }
-
- public void shrink(boolean checkTime, boolean keepAlive) {
- try {
- lock.lockInterruptibly();
- } catch (InterruptedException e) {
- return;
- }
-
- int evictCount = 0;
- int keepAliveCount = 0;
- try {
- if (!inited) {
- return;
- }
-
- final int checkCount = poolingCount - minIdle;
- final long currentTimeMillis = System.currentTimeMillis();
- for (int i = 0; i < poolingCount; ++i) {
- DruidConnectionHolder connection = connections[i];
-
- if (checkTime) {
- if (phyTimeoutMillis > 0) {
- long phyConnectTimeMillis = currentTimeMillis - connection.connectTimeMillis;
- if (phyConnectTimeMillis > phyTimeoutMillis) {
- evictConnections[evictCount++] = connection;
- continue;
- }
- }
-
- long idleMillis = currentTimeMillis - connection.lastActiveTimeMillis;
-
- if (idleMillis < minEvictableIdleTimeMillis
- && idleMillis < keepAliveBetweenTimeMillis
- ) {
- break;
- }
-
- if (idleMillis >= minEvictableIdleTimeMillis) {
- if (checkTime && i < checkCount) {
- evictConnections[evictCount++] = connection;
- continue;
- } else if (idleMillis > maxEvictableIdleTimeMillis) {
- evictConnections[evictCount++] = connection;
- continue;
- }
- }
-
- if (keepAlive && idleMillis >= keepAliveBetweenTimeMillis) {
- keepAliveConnections[keepAliveCount++] = connection;
- }
- } else {
- if (i < checkCount) {
- evictConnections[evictCount++] = connection;
- } else {
- break;
- }
- }
- }
-
- int removeCount = evictCount + keepAliveCount;
- if (removeCount > 0) {
- System.arraycopy(connections, removeCount, connections, 0, poolingCount - removeCount);
- Arrays.fill(connections, poolingCount - removeCount, poolingCount, null);
- poolingCount -= removeCount;
- }
- keepAliveCheckCount += keepAliveCount;
- } finally {
- lock.unlock();
- }
-
- if (evictCount > 0) {
- for (int i = 0; i < evictCount; ++i) {
- DruidConnectionHolder item = evictConnections[i];
- Connection connection = item.getConnection();
- JdbcUtils.close(connection);
- destroyCountUpdater.incrementAndGet(this);
- }
- Arrays.fill(evictConnections, null);
- }
-
- if (keepAliveCount > 0) {
- // keep order
- for (int i = keepAliveCount - 1; i >= 0; --i) {
- DruidConnectionHolder holer = keepAliveConnections[i];
- Connection connection = holer.getConnection();
- holer.incrementKeepAliveCheckCount();
-
- boolean validate = false;
- try {
- this.validateConnection(connection);
- validate = true;
- } catch (Throwable error) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("keepAliveErr", error);
- }
- // skip
- }
-
- boolean discard = !validate;
- if (validate) {
- holer.lastKeepTimeMillis = System.currentTimeMillis();
- boolean putOk = put(holer);
- if (!putOk) {
- discard = true;
- }
- }
-
- if (discard) {
- try {
- connection.close();
- } catch (Exception e) {
- // skip
- }
-
- lock.lock();
- try {
- discardCount++;
-
- if (activeCount <= minIdle) {
- emptySignal();
- }
- } finally {
- lock.unlock();
- }
- }
- }
- this.getDataSourceStat().addKeepAliveCheckCount(keepAliveCount);
- Arrays.fill(keepAliveConnections, null);
- }
- }
-
- public int getWaitThreadCount() {
- lock.lock();
- try {
- return lock.getWaitQueueLength(notEmpty);
- } finally {
- lock.unlock();
- }
- }
-
- public long getNotEmptyWaitCount() {
- return notEmptyWaitCount;
- }
-
- public int getNotEmptyWaitThreadCount() {
- lock.lock();
- try {
- return notEmptyWaitThreadCount;
- } finally {
- lock.unlock();
- }
- }
-
- public int getNotEmptyWaitThreadPeak() {
- lock.lock();
- try {
- return notEmptyWaitThreadPeak;
- } finally {
- lock.unlock();
- }
- }
-
- public long getNotEmptySignalCount() {
- return notEmptySignalCount;
- }
-
- public long getNotEmptyWaitMillis() {
- return notEmptyWaitNanos / (1000 * 1000);
- }
-
- public long getNotEmptyWaitNanos() {
- return notEmptyWaitNanos;
- }
-
- public int getLockQueueLength() {
- return lock.getQueueLength();
- }
-
- public int getActivePeak() {
- return activePeak;
- }
-
- public Date getActivePeakTime() {
- if (activePeakTime <= 0) {
- return null;
- }
-
- return new Date(activePeakTime);
- }
-
- public String dump() {
- lock.lock();
- try {
- return this.toString();
- } finally {
- lock.unlock();
- }
- }
-
- public long getErrorCount() {
- return this.errorCount;
- }
-
- public String toString() {
- StringBuilder buf = new StringBuilder();
-
- buf.append("{");
-
- buf.append("\n\tCreateTime:\"");
- buf.append(Utils.toString(getCreatedTime()));
- buf.append("\"");
-
- buf.append(",\n\tActiveCount:");
- buf.append(getActiveCount());
-
- buf.append(",\n\tPoolingCount:");
- buf.append(getPoolingCount());
-
- buf.append(",\n\tCreateCount:");
- buf.append(getCreateCount());
-
- buf.append(",\n\tDestroyCount:");
- buf.append(getDestroyCount());
-
- buf.append(",\n\tCloseCount:");
- buf.append(getCloseCount());
-
- buf.append(",\n\tConnectCount:");
- buf.append(getConnectCount());
-
- buf.append(",\n\tConnections:[");
- for (int i = 0; i < poolingCount; ++i) {
- DruidConnectionHolder conn = connections[i];
- if (conn != null) {
- if (i != 0) {
- buf.append(",");
- }
- buf.append("\n\t\t");
- buf.append(conn.toString());
- }
- }
- buf.append("\n\t]");
-
- buf.append("\n}");
-
- if (this.isPoolPreparedStatements()) {
- buf.append("\n\n[");
- for (int i = 0; i < poolingCount; ++i) {
- DruidConnectionHolder conn = connections[i];
- if (conn != null) {
- if (i != 0) {
- buf.append(",");
- }
- buf.append("\n\t{\n\tID:");
- buf.append(System.identityHashCode(conn.getConnection()));
- PreparedStatementPool pool = conn.getStatementPool();
-
- buf.append(", \n\tpoolStatements:[");
-
- int entryIndex = 0;
- try {
- for (Map.Entry<PreparedStatementKey, PreparedStatementHolder> entry : pool.getMap().entrySet()) {
- if (entryIndex != 0) {
- buf.append(",");
- }
- buf.append("\n\t\t{hitCount:");
- buf.append(entry.getValue().getHitCount());
- buf.append(",sql:\"");
- buf.append(entry.getKey().getSql());
- buf.append("\"");
- buf.append("\t}");
-
- entryIndex++;
- }
- } catch (ConcurrentModificationException e) {
- // skip ..
- }
-
- buf.append("\n\t\t]");
-
- buf.append("\n\t}");
- }
- }
- buf.append("\n]");
- }
-
- return buf.toString();
- }
-
- public List<Map<String, Object>> getPoolingConnectionInfo() {
- List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
- lock.lock();
- try {
- for (int i = 0; i < poolingCount; ++i) {
- DruidConnectionHolder connHolder = connections[i];
- Connection conn = connHolder.getConnection();
-
- Map<String, Object> map = new LinkedHashMap<String, Object>();
- map.put("id", System.identityHashCode(conn));
- map.put("connectionId", connHolder.getConnectionId());
- map.put("useCount", connHolder.getUseCount());
- if (connHolder.lastActiveTimeMillis > 0) {
- map.put("lastActiveTime", new Date(connHolder.lastActiveTimeMillis));
- }
- if (connHolder.lastKeepTimeMillis > 0) {
- map.put("lastKeepTimeMillis", new Date(connHolder.lastKeepTimeMillis));
- }
- map.put("connectTime", new Date(connHolder.getTimeMillis()));
- map.put("holdability", connHolder.getUnderlyingHoldability());
- map.put("transactionIsolation", connHolder.getUnderlyingTransactionIsolation());
- map.put("autoCommit", connHolder.underlyingAutoCommit);
- map.put("readoOnly", connHolder.isUnderlyingReadOnly());
-
- if (connHolder.isPoolPreparedStatements()) {
- List<Map<String, Object>> stmtCache = new ArrayList<Map<String, Object>>();
- PreparedStatementPool stmtPool = connHolder.getStatementPool();
- for (PreparedStatementHolder stmtHolder : stmtPool.getMap().values()) {
- Map<String, Object> stmtInfo = new LinkedHashMap<String, Object>();
-
- stmtInfo.put("sql", stmtHolder.key.getSql());
- stmtInfo.put("defaultRowPrefetch", stmtHolder.getDefaultRowPrefetch());
- stmtInfo.put("rowPrefetch", stmtHolder.getRowPrefetch());
- stmtInfo.put("hitCount", stmtHolder.getHitCount());
-
- stmtCache.add(stmtInfo);
- }
-
- map.put("pscache", stmtCache);
- }
- map.put("keepAliveCheckCount", connHolder.getKeepAliveCheckCount());
-
- list.add(map);
- }
- } finally {
- lock.unlock();
- }
- return list;
- }
-
- public void logTransaction(TransactionInfo info) {
- long transactionMillis = info.getEndTimeMillis() - info.getStartTimeMillis();
- if (transactionThresholdMillis > 0 && transactionMillis > transactionThresholdMillis) {
- StringBuilder buf = new StringBuilder();
- buf.append("long time transaction, take ");
- buf.append(transactionMillis);
- buf.append(" ms : ");
- for (String sql : info.getSqlList()) {
- buf.append(sql);
- buf.append(";");
- }
- LOG.error(buf.toString(), new TransactionTimeoutException());
- }
- }
-
- @Override
- public String getVersion() {
- return VERSION.getVersionNumber();
- }
-
- @Override
- public JdbcDataSourceStat getDataSourceStat() {
- return dataSourceStat;
- }
-
- public Object clone() throws CloneNotSupportedException {
- return cloneDruidDataSource();
- }
-
- public DruidDataSource cloneDruidDataSource() {
- DruidDataSource x = new DruidDataSource();
-
- cloneTo(x);
-
- return x;
- }
-
- public Map<String, Object> getStatDataForMBean() {
- try {
- Map<String, Object> map = new HashMap<String, Object>();
-
- // 0 - 4
- map.put("Name", this.getName());
- map.put("URL", this.getUrl());
- map.put("CreateCount", this.getCreateCount());
- map.put("DestroyCount", this.getDestroyCount());
- map.put("ConnectCount", this.getConnectCount());
-
- // 5 - 9
- map.put("CloseCount", this.getCloseCount());
- map.put("ActiveCount", this.getActiveCount());
- map.put("PoolingCount", this.getPoolingCount());
- map.put("LockQueueLength", this.getLockQueueLength());
- map.put("WaitThreadCount", this.getNotEmptyWaitThreadPeak());
-
- // 10 - 14
- map.put("InitialSize", this.getInitialSize());
- map.put("MaxActive", this.getMaxActive());
- map.put("MinIdle", this.getMinIdle());
- map.put("PoolPreparedStatements", this.isPoolPreparedStatements());
- map.put("TestOnBorrow", this.isTestOnBorrow());
-
- // 15 - 19
- map.put("TestOnReturn", this.isTestOnReturn());
- map.put("MinEvictableIdleTimeMillis", this.minEvictableIdleTimeMillis);
- map.put("ConnectErrorCount", this.getConnectErrorCount());
- map.put("CreateTimespanMillis", this.getCreateTimespanMillis());
- map.put("DbType", this.dbType);
-
- // 20 - 24
- map.put("ValidationQuery", this.getValidationQuery());
- map.put("ValidationQueryTimeout", this.getValidationQueryTimeout());
- map.put("DriverClassName", this.getDriverClassName());
- map.put("Username", this.getUsername());
- map.put("RemoveAbandonedCount", this.getRemoveAbandonedCount());
-
- // 25 - 29
- map.put("NotEmptyWaitCount", this.getNotEmptyWaitCount());
- map.put("NotEmptyWaitNanos", this.getNotEmptyWaitNanos());
- map.put("ErrorCount", this.getErrorCount());
- map.put("ReusePreparedStatementCount", this.getCachedPreparedStatementHitCount());
- map.put("StartTransactionCount", this.getStartTransactionCount());
-
- // 30 - 34
- map.put("CommitCount", this.getCommitCount());
- map.put("RollbackCount", this.getRollbackCount());
- map.put("LastError", JMXUtils.getErrorCompositeData(this.getLastError()));
- map.put("LastCreateError", JMXUtils.getErrorCompositeData(this.getLastCreateError()));
- map.put("PreparedStatementCacheDeleteCount", this.getCachedPreparedStatementDeleteCount());
-
- // 35 - 39
- map.put("PreparedStatementCacheAccessCount", this.getCachedPreparedStatementAccessCount());
- map.put("PreparedStatementCacheMissCount", this.getCachedPreparedStatementMissCount());
- map.put("PreparedStatementCacheHitCount", this.getCachedPreparedStatementHitCount());
- map.put("PreparedStatementCacheCurrentCount", this.getCachedPreparedStatementCount());
- map.put("Version", this.getVersion());
-
- // 40 -
- map.put("LastErrorTime", this.getLastErrorTime());
- map.put("LastCreateErrorTime", this.getLastCreateErrorTime());
- map.put("CreateErrorCount", this.getCreateErrorCount());
- map.put("DiscardCount", this.getDiscardCount());
- map.put("ExecuteQueryCount", this.getExecuteQueryCount());
-
- map.put("ExecuteUpdateCount", this.getExecuteUpdateCount());
-
- return map;
- } catch (JMException ex) {
- throw new IllegalStateException("getStatData error", ex);
- }
- }
-
- public Map<String, Object> getStatData() {
- final int activeCount;
- final int activePeak;
- final Date activePeakTime;
-
- final int poolingCount;
- final int poolingPeak;
- final Date poolingPeakTime;
-
- final long connectCount;
- final long closeCount;
-
- lock.lock();
- try {
- poolingCount = this.poolingCount;
- poolingPeak = this.poolingPeak;
- poolingPeakTime = this.getPoolingPeakTime();
-
- activeCount = this.activeCount;
- activePeak = this.activePeak;
- activePeakTime = this.getActivePeakTime();
-
- connectCount = this.connectCount;
- closeCount = this.closeCount;
- } finally {
- lock.unlock();
- }
- Map<String, Object> dataMap = new LinkedHashMap<String, Object>();
-
- dataMap.put("Identity", System.identityHashCode(this));
- dataMap.put("Name", this.getName());
- dataMap.put("DbType", this.dbType);
- dataMap.put("DriverClassName", this.getDriverClassName());
-
- dataMap.put("URL", this.getUrl());
- dataMap.put("UserName", this.getUsername());
- dataMap.put("FilterClassNames", this.getFilterClassNames());
-
- dataMap.put("WaitThreadCount", this.getWaitThreadCount());
- dataMap.put("NotEmptyWaitCount", this.getNotEmptyWaitCount());
- dataMap.put("NotEmptyWaitMillis", this.getNotEmptyWaitMillis());
-
- dataMap.put("PoolingCount", poolingCount);
- dataMap.put("PoolingPeak", poolingPeak);
- dataMap.put("PoolingPeakTime", poolingPeakTime);
-
- dataMap.put("ActiveCount", activeCount);
- dataMap.put("ActivePeak", activePeak);
- dataMap.put("ActivePeakTime", activePeakTime);
-
- dataMap.put("InitialSize", this.getInitialSize());
- dataMap.put("MinIdle", this.getMinIdle());
- dataMap.put("MaxActive", this.getMaxActive());
-
- dataMap.put("QueryTimeout", this.getQueryTimeout());
- dataMap.put("TransactionQueryTimeout", this.getTransactionQueryTimeout());
- dataMap.put("LoginTimeout", this.getLoginTimeout());
- dataMap.put("ValidConnectionCheckerClassName", this.getValidConnectionCheckerClassName());
- dataMap.put("ExceptionSorterClassName", this.getExceptionSorterClassName());
-
- dataMap.put("TestOnBorrow", this.isTestOnBorrow());
- dataMap.put("TestOnReturn", this.isTestOnReturn());
- dataMap.put("TestWhileIdle", this.isTestWhileIdle());
-
- dataMap.put("DefaultAutoCommit", this.isDefaultAutoCommit());
- dataMap.put("DefaultReadOnly", this.getDefaultReadOnly());
- dataMap.put("DefaultTransactionIsolation", this.getDefaultTransactionIsolation());
-
- dataMap.put("LogicConnectCount", connectCount);
- dataMap.put("LogicCloseCount", closeCount);
- dataMap.put("LogicConnectErrorCount", this.getConnectErrorCount());
-
- dataMap.put("PhysicalConnectCount", this.getCreateCount());
- dataMap.put("PhysicalCloseCount", this.getDestroyCount());
- dataMap.put("PhysicalConnectErrorCount", this.getCreateErrorCount());
-
- dataMap.put("ExecuteCount", this.getExecuteCount());
- dataMap.put("ExecuteUpdateCount", this.getExecuteUpdateCount());
- dataMap.put("ExecuteQueryCount", this.getExecuteQueryCount());
- dataMap.put("ExecuteBatchCount", this.getExecuteBatchCount());
- dataMap.put("ErrorCount", this.getErrorCount());
- dataMap.put("CommitCount", this.getCommitCount());
- dataMap.put("RollbackCount", this.getRollbackCount());
-
- dataMap.put("PSCacheAccessCount", this.getCachedPreparedStatementAccessCount());
- dataMap.put("PSCacheHitCount", this.getCachedPreparedStatementHitCount());
- dataMap.put("PSCacheMissCount", this.getCachedPreparedStatementMissCount());
-
- dataMap.put("StartTransactionCount", this.getStartTransactionCount());
- dataMap.put("TransactionHistogram", this.getTransactionHistogramValues());
-
- dataMap.put("ConnectionHoldTimeHistogram", this.getDataSourceStat().getConnectionHoldHistogram().toArray());
- dataMap.put("RemoveAbandoned", this.isRemoveAbandoned());
- dataMap.put("ClobOpenCount", this.getDataSourceStat().getClobOpenCount());
- dataMap.put("BlobOpenCount", this.getDataSourceStat().getBlobOpenCount());
- dataMap.put("KeepAliveCheckCount", this.getDataSourceStat().getKeepAliveCheckCount());
-
- dataMap.put("KeepAlive", this.isKeepAlive());
- dataMap.put("FailFast", this.isFailFast());
- dataMap.put("MaxWait", this.getMaxWait());
- dataMap.put("MaxWaitThreadCount", this.getMaxWaitThreadCount());
- dataMap.put("PoolPreparedStatements", this.isPoolPreparedStatements());
- dataMap.put("MaxPoolPreparedStatementPerConnectionSize", this.getMaxPoolPreparedStatementPerConnectionSize());
- dataMap.put("MinEvictableIdleTimeMillis", this.minEvictableIdleTimeMillis);
- dataMap.put("MaxEvictableIdleTimeMillis", this.maxEvictableIdleTimeMillis);
-
- dataMap.put("LogDifferentThread", isLogDifferentThread());
- dataMap.put("RecycleErrorCount", getRecycleErrorCount());
- dataMap.put("PreparedStatementOpenCount", getPreparedStatementCount());
- dataMap.put("PreparedStatementClosedCount", getClosedPreparedStatementCount());
-
- dataMap.put("UseUnfairLock", isUseUnfairLock());
- dataMap.put("InitGlobalVariants", isInitGlobalVariants());
- dataMap.put("InitVariants", isInitVariants());
- return dataMap;
- }
-
- public JdbcSqlStat getSqlStat(int sqlId) {
- return this.getDataSourceStat().getSqlStat(sqlId);
- }
-
- public JdbcSqlStat getSqlStat(long sqlId) {
- return this.getDataSourceStat().getSqlStat(sqlId);
- }
-
- public Map<String, JdbcSqlStat> getSqlStatMap() {
- return this.getDataSourceStat().getSqlStatMap();
- }
-
- public Map<String, Object> getWallStatMap() {
- WallProviderStatValue wallStatValue = getWallStatValue(false);
-
- if (wallStatValue != null) {
- return wallStatValue.toMap();
- }
-
- return null;
- }
-
- public WallProviderStatValue getWallStatValue(boolean reset) {
- for (Filter filter : this.filters) {
- if (filter instanceof WallFilter) {
- WallFilter wallFilter = (WallFilter) filter;
- return wallFilter.getProvider().getStatValue(reset);
- }
- }
-
- return null;
- }
-
- public Lock getLock() {
- return lock;
- }
-
- @Override
- public boolean isWrapperFor(Class<?> iface) {
- for (Filter filter : this.filters) {
- if (filter.isWrapperFor(iface)) {
- return true;
- }
- }
-
- if (this.statLogger != null
- && (this.statLogger.getClass() == iface || DruidDataSourceStatLogger.class == iface)) {
- return true;
- }
-
- return super.isWrapperFor(iface);
- }
-
- @SuppressWarnings("unchecked")
- public <T> T unwrap(Class<T> iface) {
- for (Filter filter : this.filters) {
- if (filter.isWrapperFor(iface)) {
- return (T) filter;
- }
- }
-
- if (this.statLogger != null
- && (this.statLogger.getClass() == iface || DruidDataSourceStatLogger.class == iface)) {
- return (T) statLogger;
- }
-
- return super.unwrap(iface);
- }
-
- public boolean isLogDifferentThread() {
- return logDifferentThread;
- }
-
- public void setLogDifferentThread(boolean logDifferentThread) {
- this.logDifferentThread = logDifferentThread;
- }
-
- public DruidPooledConnection tryGetConnection() throws SQLException {
- if (poolingCount == 0) {
- return null;
- }
- return getConnection();
- }
-
- @Override
- public int fill() throws SQLException {
- return this.fill(this.maxActive);
- }
-
- @Override
- public int fill(int toCount) throws SQLException {
- if (closed) {
- throw new DataSourceClosedException("dataSource already closed at " + new Date(closeTimeMillis));
- }
-
- if (toCount < 0) {
- throw new IllegalArgumentException("toCount can't not be less than zero");
- }
-
- init();
-
- if (toCount > this.maxActive) {
- toCount = this.maxActive;
- }
-
- int fillCount = 0;
- for (;;) {
- try {
- lock.lockInterruptibly();
- } catch (InterruptedException e) {
- connectErrorCountUpdater.incrementAndGet(this);
- throw new SQLException("interrupt", e);
- }
-
- boolean fillable = this.isFillable(toCount);
-
- lock.unlock();
-
- if (!fillable) {
- break;
- }
-
- DruidConnectionHolder holder;
- try {
- PhysicalConnectionInfo pyConnInfo = createPhysicalConnection();
- holder = new DruidConnectionHolder(this, pyConnInfo);
- } catch (SQLException e) {
- LOG.error("fill connection error, url: " + this.jdbcUrl, e);
- connectErrorCountUpdater.incrementAndGet(this);
- throw e;
- }
-
- try {
- lock.lockInterruptibly();
- } catch (InterruptedException e) {
- connectErrorCountUpdater.incrementAndGet(this);
- throw new SQLException("interrupt", e);
- }
-
- try {
- if (!this.isFillable(toCount)) {
- JdbcUtils.close(holder.getConnection());
- LOG.info("fill connections skip.");
- break;
- }
- this.putLast(holder, System.currentTimeMillis());
- fillCount++;
- } finally {
- lock.unlock();
- }
- }
-
- if (LOG.isInfoEnabled()) {
- LOG.info("fill " + fillCount + " connections");
- }
-
- return fillCount;
- }
-
- private boolean isFillable(int toCount) {
- int currentCount = this.poolingCount + this.activeCount;
- if (currentCount >= toCount || currentCount >= this.maxActive) {
- return false;
- } else {
- return true;
- }
- }
-
- public boolean isFull() {
- lock.lock();
- try {
- return this.poolingCount + this.activeCount >= this.maxActive;
- } finally {
- lock.unlock();
- }
- }
-
- private void emptySignal() {
- if (createScheduler == null) {
- empty.signal();
- return;
- }
-
- if (createTaskCount >= maxCreateTaskCount) {
- return;
- }
-
- if (activeCount + poolingCount + createTaskCount >= maxActive) {
- return;
- }
-
- createTaskCount++;
- CreateConnectionTask task = new CreateConnectionTask();
- this.createSchedulerFuture = createScheduler.submit(task);
- }
-
- @Override
- public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {
- if (server != null) {
- try {
- if (server.isRegistered(name)) {
- server.unregisterMBean(name);
- }
- } catch (Exception ex) {
- LOG.warn("DruidDataSource preRegister error", ex);
- }
- }
- return name;
- }
-
- @Override
- public void postRegister(Boolean registrationDone) {
-
- }
-
- @Override
- public void preDeregister() throws Exception {
-
- }
-
- @Override
- public void postDeregister() {
-
- }
-
- public boolean isClosed() {
- return this.closed;
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。