当前位置:   article > 正文

阿里DruidDataSource访问RDS安全级别受限问题排查_exceptionsorter com.alibaba.druid.pool.vendor.mysq

exceptionsorter com.alibaba.druid.pool.vendor.mysqlexceptionsorter

目录

限制问题日志

错误代码跟踪 

异常问题分析

DruidDataSource源码

参考阅读


首先声明:这个锅不是 DruidDataSource的问题,请放心使用 DruidDataSource。

DS是关系型数据库服务(Relational Database Service)的简称,是一种即开即用、稳定可靠、可弹性伸缩的在线数据库服务。具有多重安全防护措施和完善的性能监控体系,并提供专业的数据库备份、恢复及优化方案,使您能专注于应用开发和业务发展。

问题描述:使用JDBC和Hikari连接RDS都可以正常启动服务,使用DruidDataSource连接RDS却启动不起来,最后是因为程序授权 license导致服务启动失败,而DruidDataSource的警告异常是系统安全级别的提示而已 。

限制问题日志

主要提示的是sun.misc.Unsafe.park(Native method) ,此问题可能是系统级别的安全限制,虽然也有AQS异常,本质上应该涉及到系统Native方法调用。

  1. sun.misc.Unsafe.park(Native Method)
  2. java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
  3. java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
  4. com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2576)
  5. 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:
  6. java.lang.Thread.sleep(Native Method)
  7. com.alibaba.druid.pool.DruidDataSource$DestroyConnectionThread.run(DruidDataSource.java:2672)
  8. 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:
  9. java.net.SocketInputStream.socketRead0(Native Method)
  10. java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
  11. java.net.SocketInputStream.read(SocketInputStream.java:171)
  12. java.net.SocketInputStream.read(SocketInputStream.java:141)
  13. java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
  14. java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
  15. java.io.BufferedInputStream.read(BufferedInputStream.java:345)
  16. sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:735)
  17. sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)
  18. sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
  19. sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
  20. net.sf.ehcache.util.UpdateChecker.getUpdateProperties(UpdateChecker.java:106)
  21. net.sf.ehcache.util.UpdateChecker.doCheck(UpdateChecker.java:70)
  22. net.sf.ehcache.util.UpdateChecker.checkForUpdate(UpdateChecker.java:60)
  23. net.sf.ehcache.util.UpdateChecker.run(UpdateChecker.java:51)
  24. java.util.TimerThread.mainLoop(Timer.java:555)
  25. java.util.TimerThread.run(Timer.java:505)
  26. 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:
  27. sun.misc.Unsafe.park(Native Method)
  28. java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
  29. java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
  30. java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
  31. java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
  32. java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
  33. java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
  34. java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  35. java.lang.Thread.run(Thread.java:748)
  36. 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:
  37. sun.misc.Unsafe.park(Native Method)
  38. java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
  39. java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
  40. java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
  41. java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
  42. java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
  43. java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
  44. java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  45. java.lang.Thread.run(Thread.java:748)

错误代码跟踪 

错误点1:

错误点2: 

异常问题分析

错误点1分析:这里是AQS队列阻塞。

 定位到park底层调用的是Native方法:这里就是将线程的进行阻塞的方法。

 setBlocker方法本身是调用本地系统Native硬件方法:

而UNSAFE的方法都是本地硬件Native方法:

问题点2是同个线程引发的问题实质上是问题1。 

DruidDataSource源码

阿里Druid项目代码:https://github.com/alibaba/druid

解决方法参考:RDS的mysql无法正常连接 ,或者更换数据源 

  1. /*
  2. * Copyright 1999-2018 Alibaba Group Holding Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.alibaba.druid.pool;
  17. import static com.alibaba.druid.util.Utils.getBoolean;
  18. import java.io.Closeable;
  19. import java.security.AccessController;
  20. import java.security.PrivilegedAction;
  21. import java.sql.Connection;
  22. import java.sql.SQLException;
  23. import java.sql.Statement;
  24. import java.util.ArrayList;
  25. import java.util.Arrays;
  26. import java.util.Collections;
  27. import java.util.ConcurrentModificationException;
  28. import java.util.Date;
  29. import java.util.HashMap;
  30. import java.util.Iterator;
  31. import java.util.LinkedHashMap;
  32. import java.util.List;
  33. import java.util.Map;
  34. import java.util.Properties;
  35. import java.util.ServiceLoader;
  36. import java.util.StringTokenizer;
  37. import java.util.TimeZone;
  38. import java.util.concurrent.CountDownLatch;
  39. import java.util.concurrent.Future;
  40. import java.util.concurrent.ScheduledFuture;
  41. import java.util.concurrent.ScheduledThreadPoolExecutor;
  42. import java.util.concurrent.TimeUnit;
  43. import java.util.concurrent.atomic.AtomicLongFieldUpdater;
  44. import java.util.concurrent.locks.Lock;
  45. import java.util.concurrent.locks.ReentrantLock;
  46. import javax.management.JMException;
  47. import javax.management.MBeanRegistration;
  48. import javax.management.MBeanServer;
  49. import javax.management.ObjectName;
  50. import javax.naming.NamingException;
  51. import javax.naming.Reference;
  52. import javax.naming.Referenceable;
  53. import javax.naming.StringRefAddr;
  54. import javax.sql.ConnectionEvent;
  55. import javax.sql.ConnectionEventListener;
  56. import javax.sql.ConnectionPoolDataSource;
  57. import javax.sql.PooledConnection;
  58. import com.alibaba.druid.Constants;
  59. import com.alibaba.druid.TransactionTimeoutException;
  60. import com.alibaba.druid.VERSION;
  61. import com.alibaba.druid.filter.AutoLoad;
  62. import com.alibaba.druid.filter.Filter;
  63. import com.alibaba.druid.filter.FilterChainImpl;
  64. import com.alibaba.druid.mock.MockDriver;
  65. import com.alibaba.druid.pool.DruidPooledPreparedStatement.PreparedStatementKey;
  66. import com.alibaba.druid.pool.vendor.DB2ExceptionSorter;
  67. import com.alibaba.druid.pool.vendor.InformixExceptionSorter;
  68. import com.alibaba.druid.pool.vendor.MSSQLValidConnectionChecker;
  69. import com.alibaba.druid.pool.vendor.MockExceptionSorter;
  70. import com.alibaba.druid.pool.vendor.MySqlExceptionSorter;
  71. import com.alibaba.druid.pool.vendor.MySqlValidConnectionChecker;
  72. import com.alibaba.druid.pool.vendor.NullExceptionSorter;
  73. import com.alibaba.druid.pool.vendor.OracleExceptionSorter;
  74. import com.alibaba.druid.pool.vendor.OracleValidConnectionChecker;
  75. import com.alibaba.druid.pool.vendor.PGExceptionSorter;
  76. import com.alibaba.druid.pool.vendor.PGValidConnectionChecker;
  77. import com.alibaba.druid.pool.vendor.SybaseExceptionSorter;
  78. import com.alibaba.druid.proxy.DruidDriver;
  79. import com.alibaba.druid.proxy.jdbc.DataSourceProxyConfig;
  80. import com.alibaba.druid.proxy.jdbc.TransactionInfo;
  81. import com.alibaba.druid.sql.ast.SQLStatement;
  82. import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
  83. import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
  84. import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
  85. import com.alibaba.druid.sql.parser.SQLParserUtils;
  86. import com.alibaba.druid.sql.parser.SQLStatementParser;
  87. import com.alibaba.druid.stat.DruidDataSourceStatManager;
  88. import com.alibaba.druid.stat.JdbcDataSourceStat;
  89. import com.alibaba.druid.stat.JdbcSqlStat;
  90. import com.alibaba.druid.stat.JdbcSqlStatValue;
  91. import com.alibaba.druid.support.logging.Log;
  92. import com.alibaba.druid.support.logging.LogFactory;
  93. import com.alibaba.druid.util.JMXUtils;
  94. import com.alibaba.druid.util.JdbcConstants;
  95. import com.alibaba.druid.util.JdbcUtils;
  96. import com.alibaba.druid.util.StringUtils;
  97. import com.alibaba.druid.util.Utils;
  98. import com.alibaba.druid.wall.WallFilter;
  99. import com.alibaba.druid.wall.WallProviderStatValue;
  100. /**
  101. * @author ljw [ljw2083@alibaba-inc.com]
  102. * @author wenshao [szujobs@hotmail.com]
  103. */
  104. public class DruidDataSource extends DruidAbstractDataSource implements DruidDataSourceMBean, ManagedDataSource, Referenceable, Closeable, Cloneable, ConnectionPoolDataSource, MBeanRegistration {
  105. private final static Log LOG = LogFactory.getLog(DruidDataSource.class);
  106. private static final long serialVersionUID = 1L;
  107. // stats
  108. private volatile long recycleErrorCount = 0L;
  109. private long connectCount = 0L;
  110. private long closeCount = 0L;
  111. private volatile long connectErrorCount = 0L;
  112. private long recycleCount = 0L;
  113. private long removeAbandonedCount = 0L;
  114. private long notEmptyWaitCount = 0L;
  115. private long notEmptySignalCount = 0L;
  116. private long notEmptyWaitNanos = 0L;
  117. private int keepAliveCheckCount = 0;
  118. private int activePeak = 0;
  119. private long activePeakTime = 0;
  120. private int poolingPeak = 0;
  121. private long poolingPeakTime = 0;
  122. // store
  123. private volatile DruidConnectionHolder[] connections;
  124. private int poolingCount = 0;
  125. private int activeCount = 0;
  126. private volatile long discardCount = 0;
  127. private int notEmptyWaitThreadCount = 0;
  128. private int notEmptyWaitThreadPeak = 0;
  129. //
  130. private DruidConnectionHolder[] evictConnections;
  131. private DruidConnectionHolder[] keepAliveConnections;
  132. // threads
  133. private volatile ScheduledFuture<?> destroySchedulerFuture;
  134. private DestroyTask destroyTask;
  135. private volatile Future<?> createSchedulerFuture;
  136. private CreateConnectionThread createConnectionThread;
  137. private DestroyConnectionThread destroyConnectionThread;
  138. private LogStatsThread logStatsThread;
  139. private int createTaskCount;
  140. private final CountDownLatch initedLatch = new CountDownLatch(2);
  141. private volatile boolean enable = true;
  142. private boolean resetStatEnable = true;
  143. private volatile long resetCount = 0L;
  144. private String initStackTrace;
  145. private volatile boolean closing = false;
  146. private volatile boolean closed = false;
  147. private long closeTimeMillis = -1L;
  148. protected JdbcDataSourceStat dataSourceStat;
  149. private boolean useGlobalDataSourceStat = false;
  150. private boolean mbeanRegistered = false;
  151. public static ThreadLocal<Long> waitNanosLocal = new ThreadLocal<Long>();
  152. private boolean logDifferentThread = true;
  153. private volatile boolean keepAlive = false;
  154. private boolean asyncInit = false;
  155. protected boolean killWhenSocketReadTimeout = false;
  156. private static List<Filter> autoFilters = null;
  157. private boolean loadSpifilterSkip = false;
  158. protected static final AtomicLongFieldUpdater<DruidDataSource> recycleErrorCountUpdater
  159. = AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "recycleErrorCount");
  160. protected static final AtomicLongFieldUpdater<DruidDataSource> connectErrorCountUpdater
  161. = AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "connectErrorCount");
  162. protected static final AtomicLongFieldUpdater<DruidDataSource> resetCountUpdater
  163. = AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "resetCount");
  164. public DruidDataSource(){
  165. this(false);
  166. }
  167. public DruidDataSource(boolean fairLock){
  168. super(fairLock);
  169. configFromPropety(System.getProperties());
  170. }
  171. public boolean isAsyncInit() {
  172. return asyncInit;
  173. }
  174. public void setAsyncInit(boolean asyncInit) {
  175. this.asyncInit = asyncInit;
  176. }
  177. public void configFromPropety(Properties properties) {
  178. {
  179. String property = properties.getProperty("druid.name");
  180. if (property != null) {
  181. this.setName(property);
  182. }
  183. }
  184. {
  185. String property = properties.getProperty("druid.url");
  186. if (property != null) {
  187. this.setUrl(property);
  188. }
  189. }
  190. {
  191. String property = properties.getProperty("druid.username");
  192. if (property != null) {
  193. this.setUsername(property);
  194. }
  195. }
  196. {
  197. String property = properties.getProperty("druid.password");
  198. if (property != null) {
  199. this.setPassword(property);
  200. }
  201. }
  202. {
  203. Boolean value = getBoolean(properties, "druid.testWhileIdle");
  204. if (value != null) {
  205. this.testWhileIdle = value;
  206. }
  207. }
  208. {
  209. Boolean value = getBoolean(properties, "druid.testOnBorrow");
  210. if (value != null) {
  211. this.testOnBorrow = value;
  212. }
  213. }
  214. {
  215. String property = properties.getProperty("druid.validationQuery");
  216. if (property != null && property.length() > 0) {
  217. this.setValidationQuery(property);
  218. }
  219. }
  220. {
  221. Boolean value = getBoolean(properties, "druid.useGlobalDataSourceStat");
  222. if (value != null) {
  223. this.setUseGlobalDataSourceStat(value);
  224. }
  225. }
  226. {
  227. Boolean value = getBoolean(properties, "druid.useGloalDataSourceStat"); // compatible for early versions
  228. if (value != null) {
  229. this.setUseGlobalDataSourceStat(value);
  230. }
  231. }
  232. {
  233. Boolean value = getBoolean(properties, "druid.asyncInit"); // compatible for early versions
  234. if (value != null) {
  235. this.setAsyncInit(value);
  236. }
  237. }
  238. {
  239. String property = properties.getProperty("druid.filters");
  240. if (property != null && property.length() > 0) {
  241. try {
  242. this.setFilters(property);
  243. } catch (SQLException e) {
  244. LOG.error("setFilters error", e);
  245. }
  246. }
  247. }
  248. {
  249. String property = properties.getProperty(Constants.DRUID_TIME_BETWEEN_LOG_STATS_MILLIS);
  250. if (property != null && property.length() > 0) {
  251. try {
  252. long value = Long.parseLong(property);
  253. this.setTimeBetweenLogStatsMillis(value);
  254. } catch (NumberFormatException e) {
  255. LOG.error("illegal property '" + Constants.DRUID_TIME_BETWEEN_LOG_STATS_MILLIS + "'", e);
  256. }
  257. }
  258. }
  259. {
  260. String property = properties.getProperty(Constants.DRUID_STAT_SQL_MAX_SIZE);
  261. if (property != null && property.length() > 0) {
  262. try {
  263. int value = Integer.parseInt(property);
  264. if (dataSourceStat != null) {
  265. dataSourceStat.setMaxSqlSize(value);
  266. }
  267. } catch (NumberFormatException e) {
  268. LOG.error("illegal property '" + Constants.DRUID_STAT_SQL_MAX_SIZE + "'", e);
  269. }
  270. }
  271. }
  272. {
  273. Boolean value = getBoolean(properties, "druid.clearFiltersEnable");
  274. if (value != null) {
  275. this.setClearFiltersEnable(value);
  276. }
  277. }
  278. {
  279. Boolean value = getBoolean(properties, "druid.resetStatEnable");
  280. if (value != null) {
  281. this.setResetStatEnable(value);
  282. }
  283. }
  284. {
  285. String property = properties.getProperty("druid.notFullTimeoutRetryCount");
  286. if (property != null && property.length() > 0) {
  287. try {
  288. int value = Integer.parseInt(property);
  289. this.setNotFullTimeoutRetryCount(value);
  290. } catch (NumberFormatException e) {
  291. LOG.error("illegal property 'druid.notFullTimeoutRetryCount'", e);
  292. }
  293. }
  294. }
  295. {
  296. String property = properties.getProperty("druid.timeBetweenEvictionRunsMillis");
  297. if (property != null && property.length() > 0) {
  298. try {
  299. long value = Long.parseLong(property);
  300. this.setTimeBetweenEvictionRunsMillis(value);
  301. } catch (NumberFormatException e) {
  302. LOG.error("illegal property 'druid.timeBetweenEvictionRunsMillis'", e);
  303. }
  304. }
  305. }
  306. {
  307. String property = properties.getProperty("druid.maxWaitThreadCount");
  308. if (property != null && property.length() > 0) {
  309. try {
  310. int value = Integer.parseInt(property);
  311. this.setMaxWaitThreadCount(value);
  312. } catch (NumberFormatException e) {
  313. LOG.error("illegal property 'druid.maxWaitThreadCount'", e);
  314. }
  315. }
  316. }
  317. {
  318. String property = properties.getProperty("druid.maxWait");
  319. if (property != null && property.length() > 0) {
  320. try {
  321. int value = Integer.parseInt(property);
  322. this.setMaxWait(value);
  323. } catch (NumberFormatException e) {
  324. LOG.error("illegal property 'druid.maxWait'", e);
  325. }
  326. }
  327. }
  328. {
  329. Boolean value = getBoolean(properties, "druid.failFast");
  330. if (value != null) {
  331. this.setFailFast(value);
  332. }
  333. }
  334. {
  335. String property = properties.getProperty("druid.phyTimeoutMillis");
  336. if (property != null && property.length() > 0) {
  337. try {
  338. long value = Long.parseLong(property);
  339. this.setPhyTimeoutMillis(value);
  340. } catch (NumberFormatException e) {
  341. LOG.error("illegal property 'druid.phyTimeoutMillis'", e);
  342. }
  343. }
  344. }
  345. {
  346. String property = properties.getProperty("druid.phyMaxUseCount");
  347. if (property != null && property.length() > 0) {
  348. try {
  349. long value = Long.parseLong(property);
  350. this.setPhyMaxUseCount(value);
  351. } catch (NumberFormatException e) {
  352. LOG.error("illegal property 'druid.phyMaxUseCount'", e);
  353. }
  354. }
  355. }
  356. {
  357. String property = properties.getProperty("druid.minEvictableIdleTimeMillis");
  358. if (property != null && property.length() > 0) {
  359. try {
  360. long value = Long.parseLong(property);
  361. this.setMinEvictableIdleTimeMillis(value);
  362. } catch (NumberFormatException e) {
  363. LOG.error("illegal property 'druid.minEvictableIdleTimeMillis'", e);
  364. }
  365. }
  366. }
  367. {
  368. String property = properties.getProperty("druid.maxEvictableIdleTimeMillis");
  369. if (property != null && property.length() > 0) {
  370. try {
  371. long value = Long.parseLong(property);
  372. this.setMaxEvictableIdleTimeMillis(value);
  373. } catch (NumberFormatException e) {
  374. LOG.error("illegal property 'druid.maxEvictableIdleTimeMillis'", e);
  375. }
  376. }
  377. }
  378. {
  379. Boolean value = getBoolean(properties, "druid.keepAlive");
  380. if (value != null) {
  381. this.setKeepAlive(value);
  382. }
  383. }
  384. {
  385. String property = properties.getProperty("druid.keepAliveBetweenTimeMillis");
  386. if (property != null && property.length() > 0) {
  387. try {
  388. long value = Long.parseLong(property);
  389. this.setKeepAliveBetweenTimeMillis(value);
  390. } catch (NumberFormatException e) {
  391. LOG.error("illegal property 'druid.keepAliveBetweenTimeMillis'", e);
  392. }
  393. }
  394. }
  395. {
  396. Boolean value = getBoolean(properties, "druid.poolPreparedStatements");
  397. if (value != null) {
  398. this.setPoolPreparedStatements0(value);
  399. }
  400. }
  401. {
  402. Boolean value = getBoolean(properties, "druid.initVariants");
  403. if (value != null) {
  404. this.setInitVariants(value);
  405. }
  406. }
  407. {
  408. Boolean value = getBoolean(properties, "druid.initGlobalVariants");
  409. if (value != null) {
  410. this.setInitGlobalVariants(value);
  411. }
  412. }
  413. {
  414. Boolean value = getBoolean(properties, "druid.useUnfairLock");
  415. if (value != null) {
  416. this.setUseUnfairLock(value);
  417. }
  418. }
  419. {
  420. String property = properties.getProperty("druid.driverClassName");
  421. if (property != null) {
  422. this.setDriverClassName(property);
  423. }
  424. }
  425. {
  426. String property = properties.getProperty("druid.initialSize");
  427. if (property != null && property.length() > 0) {
  428. try {
  429. int value = Integer.parseInt(property);
  430. this.setInitialSize(value);
  431. } catch (NumberFormatException e) {
  432. LOG.error("illegal property 'druid.initialSize'", e);
  433. }
  434. }
  435. }
  436. {
  437. String property = properties.getProperty("druid.minIdle");
  438. if (property != null && property.length() > 0) {
  439. try {
  440. int value = Integer.parseInt(property);
  441. this.setMinIdle(value);
  442. } catch (NumberFormatException e) {
  443. LOG.error("illegal property 'druid.minIdle'", e);
  444. }
  445. }
  446. }
  447. {
  448. String property = properties.getProperty("druid.maxActive");
  449. if (property != null && property.length() > 0) {
  450. try {
  451. int value = Integer.parseInt(property);
  452. this.setMaxActive(value);
  453. } catch (NumberFormatException e) {
  454. LOG.error("illegal property 'druid.maxActive'", e);
  455. }
  456. }
  457. }
  458. {
  459. Boolean value = getBoolean(properties, "druid.killWhenSocketReadTimeout");
  460. if (value != null) {
  461. setKillWhenSocketReadTimeout(value);
  462. }
  463. }
  464. {
  465. String property = properties.getProperty("druid.connectProperties");
  466. if (property != null) {
  467. this.setConnectionProperties(property);
  468. }
  469. }
  470. {
  471. String property = properties.getProperty("druid.maxPoolPreparedStatementPerConnectionSize");
  472. if (property != null && property.length() > 0) {
  473. try {
  474. int value = Integer.parseInt(property);
  475. this.setMaxPoolPreparedStatementPerConnectionSize(value);
  476. } catch (NumberFormatException e) {
  477. LOG.error("illegal property 'druid.maxPoolPreparedStatementPerConnectionSize'", e);
  478. }
  479. }
  480. }
  481. {
  482. String property = properties.getProperty("druid.initConnectionSqls");
  483. if (property != null && property.length() > 0) {
  484. try {
  485. StringTokenizer tokenizer = new StringTokenizer(property, ";");
  486. setConnectionInitSqls(Collections.list(tokenizer));
  487. } catch (NumberFormatException e) {
  488. LOG.error("illegal property 'druid.initConnectionSqls'", e);
  489. }
  490. }
  491. }
  492. {
  493. String property = System.getProperty("druid.load.spifilter.skip");
  494. if (property != null && !"false".equals(property)) {
  495. loadSpifilterSkip = true;
  496. }
  497. }
  498. }
  499. public boolean isKillWhenSocketReadTimeout() {
  500. return killWhenSocketReadTimeout;
  501. }
  502. public void setKillWhenSocketReadTimeout(boolean killWhenSocketTimeOut) {
  503. this.killWhenSocketReadTimeout = killWhenSocketTimeOut;
  504. }
  505. public boolean isUseGlobalDataSourceStat() {
  506. return useGlobalDataSourceStat;
  507. }
  508. public void setUseGlobalDataSourceStat(boolean useGlobalDataSourceStat) {
  509. this.useGlobalDataSourceStat = useGlobalDataSourceStat;
  510. }
  511. public boolean isKeepAlive() {
  512. return keepAlive;
  513. }
  514. public void setKeepAlive(boolean keepAlive) {
  515. this.keepAlive = keepAlive;
  516. }
  517. public String getInitStackTrace() {
  518. return initStackTrace;
  519. }
  520. public boolean isResetStatEnable() {
  521. return resetStatEnable;
  522. }
  523. public void setResetStatEnable(boolean resetStatEnable) {
  524. this.resetStatEnable = resetStatEnable;
  525. if (dataSourceStat != null) {
  526. dataSourceStat.setResetStatEnable(resetStatEnable);
  527. }
  528. }
  529. public long getDiscardCount() {
  530. return discardCount;
  531. }
  532. public void restart() throws SQLException {
  533. lock.lock();
  534. try {
  535. if (activeCount > 0) {
  536. throw new SQLException("can not restart, activeCount not zero. " + activeCount);
  537. }
  538. if (LOG.isInfoEnabled()) {
  539. LOG.info("{dataSource-" + this.getID() + "} restart");
  540. }
  541. this.close();
  542. this.resetStat();
  543. this.inited = false;
  544. this.enable = true;
  545. this.closed = false;
  546. } finally {
  547. lock.unlock();
  548. }
  549. }
  550. public void resetStat() {
  551. if (!isResetStatEnable()) {
  552. return;
  553. }
  554. lock.lock();
  555. try {
  556. connectCount = 0;
  557. closeCount = 0;
  558. discardCount = 0;
  559. recycleCount = 0;
  560. createCount = 0L;
  561. directCreateCount = 0;
  562. destroyCount = 0L;
  563. removeAbandonedCount = 0;
  564. notEmptyWaitCount = 0;
  565. notEmptySignalCount = 0L;
  566. notEmptyWaitNanos = 0;
  567. activePeak = activeCount;
  568. activePeakTime = 0;
  569. poolingPeak = 0;
  570. createTimespan = 0;
  571. lastError = null;
  572. lastErrorTimeMillis = 0;
  573. lastCreateError = null;
  574. lastCreateErrorTimeMillis = 0;
  575. } finally {
  576. lock.unlock();
  577. }
  578. connectErrorCountUpdater.set(this, 0);
  579. errorCountUpdater.set(this, 0);
  580. commitCountUpdater.set(this, 0);
  581. rollbackCountUpdater.set(this, 0);
  582. startTransactionCountUpdater.set(this, 0);
  583. cachedPreparedStatementHitCountUpdater.set(this, 0);
  584. closedPreparedStatementCountUpdater.set(this, 0);
  585. preparedStatementCountUpdater.set(this, 0);
  586. transactionHistogram.reset();
  587. cachedPreparedStatementDeleteCountUpdater.set(this, 0);
  588. recycleErrorCountUpdater.set(this, 0);
  589. resetCountUpdater.incrementAndGet(this);
  590. }
  591. public long getResetCount() {
  592. return this.resetCount;
  593. }
  594. public boolean isEnable() {
  595. return enable;
  596. }
  597. public void setEnable(boolean enable) {
  598. lock.lock();
  599. try {
  600. this.enable = enable;
  601. if (!enable) {
  602. notEmpty.signalAll();
  603. notEmptySignalCount++;
  604. }
  605. } finally {
  606. lock.unlock();
  607. }
  608. }
  609. public void setPoolPreparedStatements(boolean value) {
  610. setPoolPreparedStatements0(value);
  611. }
  612. private void setPoolPreparedStatements0(boolean value) {
  613. if (this.poolPreparedStatements == value) {
  614. return;
  615. }
  616. this.poolPreparedStatements = value;
  617. if (!inited) {
  618. return;
  619. }
  620. if (LOG.isInfoEnabled()) {
  621. LOG.info("set poolPreparedStatements " + this.poolPreparedStatements + " -> " + value);
  622. }
  623. if (!value) {
  624. lock.lock();
  625. try {
  626. for (int i = 0; i < poolingCount; ++i) {
  627. DruidConnectionHolder connection = connections[i];
  628. for (PreparedStatementHolder holder : connection.getStatementPool().getMap().values()) {
  629. closePreapredStatement(holder);
  630. }
  631. connection.getStatementPool().getMap().clear();
  632. }
  633. } finally {
  634. lock.unlock();
  635. }
  636. }
  637. }
  638. public void setMaxActive(int maxActive) {
  639. if (this.maxActive == maxActive) {
  640. return;
  641. }
  642. if (maxActive == 0) {
  643. throw new IllegalArgumentException("maxActive can't not set zero");
  644. }
  645. if (!inited) {
  646. this.maxActive = maxActive;
  647. return;
  648. }
  649. if (maxActive < this.minIdle) {
  650. throw new IllegalArgumentException("maxActive less than minIdle, " + maxActive + " < " + this.minIdle);
  651. }
  652. if (LOG.isInfoEnabled()) {
  653. LOG.info("maxActive changed : " + this.maxActive + " -> " + maxActive);
  654. }
  655. lock.lock();
  656. try {
  657. int allCount = this.poolingCount + this.activeCount;
  658. if (maxActive > allCount) {
  659. this.connections = Arrays.copyOf(this.connections, maxActive);
  660. evictConnections = new DruidConnectionHolder[maxActive];
  661. keepAliveConnections = new DruidConnectionHolder[maxActive];
  662. } else {
  663. this.connections = Arrays.copyOf(this.connections, allCount);
  664. evictConnections = new DruidConnectionHolder[allCount];
  665. keepAliveConnections = new DruidConnectionHolder[allCount];
  666. }
  667. this.maxActive = maxActive;
  668. } finally {
  669. lock.unlock();
  670. }
  671. }
  672. @SuppressWarnings("rawtypes")
  673. public void setConnectProperties(Properties properties) {
  674. if (properties == null) {
  675. properties = new Properties();
  676. }
  677. boolean equals;
  678. if (properties.size() == this.connectProperties.size()) {
  679. equals = true;
  680. for (Map.Entry entry : properties.entrySet()) {
  681. Object value = this.connectProperties.get(entry.getKey());
  682. Object entryValue = entry.getValue();
  683. if (value == null && entryValue != null) {
  684. equals = false;
  685. break;
  686. }
  687. if (!value.equals(entry.getValue())) {
  688. equals = false;
  689. break;
  690. }
  691. }
  692. } else {
  693. equals = false;
  694. }
  695. if (!equals) {
  696. if (inited && LOG.isInfoEnabled()) {
  697. LOG.info("connectProperties changed : " + this.connectProperties + " -> " + properties);
  698. }
  699. configFromPropety(properties);
  700. for (Filter filter : this.filters) {
  701. filter.configFromProperties(properties);
  702. }
  703. if (exceptionSorter != null) {
  704. exceptionSorter.configFromProperties(properties);
  705. }
  706. if (validConnectionChecker != null) {
  707. validConnectionChecker.configFromProperties(properties);
  708. }
  709. if (statLogger != null) {
  710. statLogger.configFromProperties(properties);
  711. }
  712. }
  713. this.connectProperties = properties;
  714. }
  715. public void init() throws SQLException {
  716. if (inited) {
  717. return;
  718. }
  719. // bug fixed for dead lock, for issue #2980
  720. DruidDriver.getInstance();
  721. final ReentrantLock lock = this.lock;
  722. try {
  723. lock.lockInterruptibly();
  724. } catch (InterruptedException e) {
  725. throw new SQLException("interrupt", e);
  726. }
  727. boolean init = false;
  728. try {
  729. if (inited) {
  730. return;
  731. }
  732. initStackTrace = Utils.toString(Thread.currentThread().getStackTrace());
  733. this.id = DruidDriver.createDataSourceId();
  734. if (this.id > 1) {
  735. long delta = (this.id - 1) * 100000;
  736. this.connectionIdSeedUpdater.addAndGet(this, delta);
  737. this.statementIdSeedUpdater.addAndGet(this, delta);
  738. this.resultSetIdSeedUpdater.addAndGet(this, delta);
  739. this.transactionIdSeedUpdater.addAndGet(this, delta);
  740. }
  741. if (this.jdbcUrl != null) {
  742. this.jdbcUrl = this.jdbcUrl.trim();
  743. initFromWrapDriverUrl();
  744. }
  745. for (Filter filter : filters) {
  746. filter.init(this);
  747. }
  748. if (this.dbType == null || this.dbType.length() == 0) {
  749. this.dbType = JdbcUtils.getDbType(jdbcUrl, null);
  750. }
  751. if (JdbcConstants.MYSQL.equals(this.dbType)
  752. || JdbcConstants.MARIADB.equals(this.dbType)
  753. || JdbcConstants.ALIYUN_ADS.equals(this.dbType)) {
  754. boolean cacheServerConfigurationSet = false;
  755. if (this.connectProperties.containsKey("cacheServerConfiguration")) {
  756. cacheServerConfigurationSet = true;
  757. } else if (this.jdbcUrl.indexOf("cacheServerConfiguration") != -1) {
  758. cacheServerConfigurationSet = true;
  759. }
  760. if (cacheServerConfigurationSet) {
  761. this.connectProperties.put("cacheServerConfiguration", "true");
  762. }
  763. }
  764. if (maxActive <= 0) {
  765. throw new IllegalArgumentException("illegal maxActive " + maxActive);
  766. }
  767. if (maxActive < minIdle) {
  768. throw new IllegalArgumentException("illegal maxActive " + maxActive);
  769. }
  770. if (getInitialSize() > maxActive) {
  771. throw new IllegalArgumentException("illegal initialSize " + this.initialSize + ", maxActive " + maxActive);
  772. }
  773. if (timeBetweenLogStatsMillis > 0 && useGlobalDataSourceStat) {
  774. throw new IllegalArgumentException("timeBetweenLogStatsMillis not support useGlobalDataSourceStat=true");
  775. }
  776. if (maxEvictableIdleTimeMillis < minEvictableIdleTimeMillis) {
  777. throw new SQLException("maxEvictableIdleTimeMillis must be grater than minEvictableIdleTimeMillis");
  778. }
  779. if (this.driverClass != null) {
  780. this.driverClass = driverClass.trim();
  781. }
  782. initFromSPIServiceLoader();
  783. if (this.driver == null) {
  784. if (this.driverClass == null || this.driverClass.isEmpty()) {
  785. this.driverClass = JdbcUtils.getDriverClassName(this.jdbcUrl);
  786. }
  787. if (MockDriver.class.getName().equals(driverClass)) {
  788. driver = MockDriver.instance;
  789. } else {
  790. if (jdbcUrl == null && (driverClass == null || driverClass.length() == 0)) {
  791. throw new SQLException("url not set");
  792. }
  793. driver = JdbcUtils.createDriver(driverClassLoader, driverClass);
  794. }
  795. } else {
  796. if (this.driverClass == null) {
  797. this.driverClass = driver.getClass().getName();
  798. }
  799. }
  800. initCheck();
  801. initExceptionSorter();
  802. initValidConnectionChecker();
  803. validationQueryCheck();
  804. if (isUseGlobalDataSourceStat()) {
  805. dataSourceStat = JdbcDataSourceStat.getGlobal();
  806. if (dataSourceStat == null) {
  807. dataSourceStat = new JdbcDataSourceStat("Global", "Global", this.dbType);
  808. JdbcDataSourceStat.setGlobal(dataSourceStat);
  809. }
  810. if (dataSourceStat.getDbType() == null) {
  811. dataSourceStat.setDbType(this.dbType);
  812. }
  813. } else {
  814. dataSourceStat = new JdbcDataSourceStat(this.name, this.jdbcUrl, this.dbType, this.connectProperties);
  815. }
  816. dataSourceStat.setResetStatEnable(this.resetStatEnable);
  817. connections = new DruidConnectionHolder[maxActive];
  818. evictConnections = new DruidConnectionHolder[maxActive];
  819. keepAliveConnections = new DruidConnectionHolder[maxActive];
  820. SQLException connectError = null;
  821. if (createScheduler != null && asyncInit) {
  822. for (int i = 0; i < initialSize; ++i) {
  823. createTaskCount++;
  824. CreateConnectionTask task = new CreateConnectionTask(true);
  825. this.createSchedulerFuture = createScheduler.submit(task);
  826. }
  827. } else if (!asyncInit) {
  828. // init connections
  829. while (poolingCount < initialSize) {
  830. try {
  831. PhysicalConnectionInfo pyConnectInfo = createPhysicalConnection();
  832. DruidConnectionHolder holder = new DruidConnectionHolder(this, pyConnectInfo);
  833. connections[poolingCount++] = holder;
  834. } catch (SQLException ex) {
  835. LOG.error("init datasource error, url: " + this.getUrl(), ex);
  836. if (initExceptionThrow) {
  837. connectError = ex;
  838. break;
  839. } else {
  840. Thread.sleep(3000);
  841. }
  842. }
  843. }
  844. if (poolingCount > 0) {
  845. poolingPeak = poolingCount;
  846. poolingPeakTime = System.currentTimeMillis();
  847. }
  848. }
  849. createAndLogThread();
  850. createAndStartCreatorThread();
  851. createAndStartDestroyThread();
  852. initedLatch.await();
  853. init = true;
  854. initedTime = new Date();
  855. registerMbean();
  856. if (connectError != null && poolingCount == 0) {
  857. throw connectError;
  858. }
  859. if (keepAlive) {
  860. // async fill to minIdle
  861. if (createScheduler != null) {
  862. for (int i = 0; i < minIdle; ++i) {
  863. createTaskCount++;
  864. CreateConnectionTask task = new CreateConnectionTask(true);
  865. this.createSchedulerFuture = createScheduler.submit(task);
  866. }
  867. } else {
  868. this.emptySignal();
  869. }
  870. }
  871. } catch (SQLException e) {
  872. LOG.error("{dataSource-" + this.getID() + "} init error", e);
  873. throw e;
  874. } catch (InterruptedException e) {
  875. throw new SQLException(e.getMessage(), e);
  876. } catch (RuntimeException e){
  877. LOG.error("{dataSource-" + this.getID() + "} init error", e);
  878. throw e;
  879. } catch (Error e){
  880. LOG.error("{dataSource-" + this.getID() + "} init error", e);
  881. throw e;
  882. } finally {
  883. inited = true;
  884. lock.unlock();
  885. if (init && LOG.isInfoEnabled()) {
  886. String msg = "{dataSource-" + this.getID();
  887. if (this.name != null && !this.name.isEmpty()) {
  888. msg += ",";
  889. msg += this.name;
  890. }
  891. msg += "} inited";
  892. LOG.info(msg);
  893. }
  894. }
  895. }
  896. private void createAndLogThread() {
  897. if (this.timeBetweenLogStatsMillis <= 0) {
  898. return;
  899. }
  900. String threadName = "Druid-ConnectionPool-Log-" + System.identityHashCode(this);
  901. logStatsThread = new LogStatsThread(threadName);
  902. logStatsThread.start();
  903. this.resetStatEnable = false;
  904. }
  905. protected void createAndStartDestroyThread() {
  906. destroyTask = new DestroyTask();
  907. if (destroyScheduler != null) {
  908. long period = timeBetweenEvictionRunsMillis;
  909. if (period <= 0) {
  910. period = 1000;
  911. }
  912. destroySchedulerFuture = destroyScheduler.scheduleAtFixedRate(destroyTask, period, period,
  913. TimeUnit.MILLISECONDS);
  914. initedLatch.countDown();
  915. return;
  916. }
  917. String threadName = "Druid-ConnectionPool-Destroy-" + System.identityHashCode(this);
  918. destroyConnectionThread = new DestroyConnectionThread(threadName);
  919. destroyConnectionThread.start();
  920. }
  921. protected void createAndStartCreatorThread() {
  922. if (createScheduler == null) {
  923. String threadName = "Druid-ConnectionPool-Create-" + System.identityHashCode(this);
  924. createConnectionThread = new CreateConnectionThread(threadName);
  925. createConnectionThread.start();
  926. return;
  927. }
  928. initedLatch.countDown();
  929. }
  930. /**
  931. * load filters from SPI ServiceLoader
  932. *
  933. * @see ServiceLoader
  934. */
  935. private void initFromSPIServiceLoader() {
  936. if (loadSpifilterSkip) {
  937. return;
  938. }
  939. if (autoFilters == null) {
  940. List<Filter> filters = new ArrayList<Filter>();
  941. ServiceLoader<Filter> autoFilterLoader = ServiceLoader.load(Filter.class);
  942. for (Filter filter : autoFilterLoader) {
  943. AutoLoad autoLoad = filter.getClass().getAnnotation(AutoLoad.class);
  944. if (autoLoad != null && autoLoad.value()) {
  945. filters.add(filter);
  946. }
  947. }
  948. autoFilters = filters;
  949. }
  950. for (Filter filter : autoFilters) {
  951. if (LOG.isInfoEnabled()) {
  952. LOG.info("load filter from spi :" + filter.getClass().getName());
  953. }
  954. addFilter(filter);
  955. }
  956. }
  957. private void initFromWrapDriverUrl() throws SQLException {
  958. if (!jdbcUrl.startsWith(DruidDriver.DEFAULT_PREFIX)) {
  959. return;
  960. }
  961. DataSourceProxyConfig config = DruidDriver.parseConfig(jdbcUrl, null);
  962. this.driverClass = config.getRawDriverClassName();
  963. LOG.error("error url : '" + jdbcUrl + "', it should be : '" + config.getRawUrl() + "'");
  964. this.jdbcUrl = config.getRawUrl();
  965. if (this.name == null) {
  966. this.name = config.getName();
  967. }
  968. for (Filter filter : config.getFilters()) {
  969. addFilter(filter);
  970. }
  971. }
  972. /**
  973. * 会去重复
  974. *
  975. * @param filter
  976. */
  977. private void addFilter(Filter filter) {
  978. boolean exists = false;
  979. for (Filter initedFilter : this.filters) {
  980. if (initedFilter.getClass() == filter.getClass()) {
  981. exists = true;
  982. break;
  983. }
  984. }
  985. if (!exists) {
  986. filter.init(this);
  987. this.filters.add(filter);
  988. }
  989. }
  990. private void validationQueryCheck() {
  991. if (!(testOnBorrow || testOnReturn || testWhileIdle)) {
  992. return;
  993. }
  994. if (this.validConnectionChecker != null) {
  995. return;
  996. }
  997. if (this.validationQuery != null && this.validationQuery.length() > 0) {
  998. return;
  999. }
  1000. String errorMessage = "";
  1001. if (testOnBorrow) {
  1002. errorMessage += "testOnBorrow is true, ";
  1003. }
  1004. if (testOnReturn) {
  1005. errorMessage += "testOnReturn is true, ";
  1006. }
  1007. if (testWhileIdle) {
  1008. errorMessage += "testWhileIdle is true, ";
  1009. }
  1010. LOG.error(errorMessage + "validationQuery not set");
  1011. }
  1012. protected void initCheck() throws SQLException {
  1013. if (JdbcUtils.ORACLE.equals(this.dbType)) {
  1014. isOracle = true;
  1015. if (driver.getMajorVersion() < 10) {
  1016. throw new SQLException("not support oracle driver " + driver.getMajorVersion() + "."
  1017. + driver.getMinorVersion());
  1018. }
  1019. if (driver.getMajorVersion() == 10 && isUseOracleImplicitCache()) {
  1020. this.getConnectProperties().setProperty("oracle.jdbc.FreeMemoryOnEnterImplicitCache", "true");
  1021. }
  1022. oracleValidationQueryCheck();
  1023. } else if (JdbcUtils.DB2.equals(dbType)) {
  1024. db2ValidationQueryCheck();
  1025. } else if (JdbcUtils.MYSQL.equals(this.dbType)
  1026. || JdbcUtils.MYSQL_DRIVER_6.equals(this.dbType)) {
  1027. isMySql = true;
  1028. }
  1029. if (removeAbandoned) {
  1030. LOG.warn("removeAbandoned is true, not use in productiion.");
  1031. }
  1032. }
  1033. private void oracleValidationQueryCheck() {
  1034. if (validationQuery == null) {
  1035. return;
  1036. }
  1037. if (validationQuery.length() == 0) {
  1038. return;
  1039. }
  1040. SQLStatementParser sqlStmtParser = SQLParserUtils.createSQLStatementParser(validationQuery, this.dbType);
  1041. List<SQLStatement> stmtList = sqlStmtParser.parseStatementList();
  1042. if (stmtList.size() != 1) {
  1043. return;
  1044. }
  1045. SQLStatement stmt = stmtList.get(0);
  1046. if (!(stmt instanceof SQLSelectStatement)) {
  1047. return;
  1048. }
  1049. SQLSelectQuery query = ((SQLSelectStatement) stmt).getSelect().getQuery();
  1050. if (query instanceof SQLSelectQueryBlock) {
  1051. if (((SQLSelectQueryBlock) query).getFrom() == null) {
  1052. LOG.error("invalid oracle validationQuery. " + validationQuery + ", may should be : " + validationQuery
  1053. + " FROM DUAL");
  1054. }
  1055. }
  1056. }
  1057. private void db2ValidationQueryCheck() {
  1058. if (validationQuery == null) {
  1059. return;
  1060. }
  1061. if (validationQuery.length() == 0) {
  1062. return;
  1063. }
  1064. SQLStatementParser sqlStmtParser = SQLParserUtils.createSQLStatementParser(validationQuery, this.dbType);
  1065. List<SQLStatement> stmtList = sqlStmtParser.parseStatementList();
  1066. if (stmtList.size() != 1) {
  1067. return;
  1068. }
  1069. SQLStatement stmt = stmtList.get(0);
  1070. if (!(stmt instanceof SQLSelectStatement)) {
  1071. return;
  1072. }
  1073. SQLSelectQuery query = ((SQLSelectStatement) stmt).getSelect().getQuery();
  1074. if (query instanceof SQLSelectQueryBlock) {
  1075. if (((SQLSelectQueryBlock) query).getFrom() == null) {
  1076. LOG.error("invalid db2 validationQuery. " + validationQuery + ", may should be : " + validationQuery
  1077. + " FROM SYSDUMMY");
  1078. }
  1079. }
  1080. }
  1081. private void initValidConnectionChecker() {
  1082. if (this.validConnectionChecker != null) {
  1083. return;
  1084. }
  1085. String realDriverClassName = driver.getClass().getName();
  1086. if (JdbcUtils.isMySqlDriver(realDriverClassName)) {
  1087. this.validConnectionChecker = new MySqlValidConnectionChecker();
  1088. } else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER)
  1089. || realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER2)) {
  1090. this.validConnectionChecker = new OracleValidConnectionChecker();
  1091. } else if (realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER)
  1092. || realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_SQLJDBC4)
  1093. || realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_JTDS)) {
  1094. this.validConnectionChecker = new MSSQLValidConnectionChecker();
  1095. } else if (realDriverClassName.equals(JdbcConstants.POSTGRESQL_DRIVER)
  1096. || realDriverClassName.equals(JdbcConstants.ENTERPRISEDB_DRIVER)) {
  1097. this.validConnectionChecker = new PGValidConnectionChecker();
  1098. }
  1099. }
  1100. private void initExceptionSorter() {
  1101. if (exceptionSorter instanceof NullExceptionSorter) {
  1102. if (driver instanceof MockDriver) {
  1103. return;
  1104. }
  1105. } else if (this.exceptionSorter != null) {
  1106. return;
  1107. }
  1108. for (Class<?> driverClass = driver.getClass();;) {
  1109. String realDriverClassName = driverClass.getName();
  1110. if (realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER) //
  1111. || realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER_6)) {
  1112. this.exceptionSorter = new MySqlExceptionSorter();
  1113. this.isMySql = true;
  1114. } else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER)
  1115. || realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER2)) {
  1116. this.exceptionSorter = new OracleExceptionSorter();
  1117. } else if (realDriverClassName.equals("com.informix.jdbc.IfxDriver")) {
  1118. this.exceptionSorter = new InformixExceptionSorter();
  1119. } else if (realDriverClassName.equals("com.sybase.jdbc2.jdbc.SybDriver")) {
  1120. this.exceptionSorter = new SybaseExceptionSorter();
  1121. } else if (realDriverClassName.equals(JdbcConstants.POSTGRESQL_DRIVER)
  1122. || realDriverClassName.equals(JdbcConstants.ENTERPRISEDB_DRIVER)) {
  1123. this.exceptionSorter = new PGExceptionSorter();
  1124. } else if (realDriverClassName.equals("com.alibaba.druid.mock.MockDriver")) {
  1125. this.exceptionSorter = new MockExceptionSorter();
  1126. } else if (realDriverClassName.contains("DB2")) {
  1127. this.exceptionSorter = new DB2ExceptionSorter();
  1128. } else {
  1129. Class<?> superClass = driverClass.getSuperclass();
  1130. if (superClass != null && superClass != Object.class) {
  1131. driverClass = superClass;
  1132. continue;
  1133. }
  1134. }
  1135. break;
  1136. }
  1137. }
  1138. @Override
  1139. public DruidPooledConnection getConnection() throws SQLException {
  1140. return getConnection(maxWait);
  1141. }
  1142. public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
  1143. init();
  1144. if (filters.size() > 0) {
  1145. FilterChainImpl filterChain = new FilterChainImpl(this);
  1146. return filterChain.dataSource_connect(this, maxWaitMillis);
  1147. } else {
  1148. return getConnectionDirect(maxWaitMillis);
  1149. }
  1150. }
  1151. @Override
  1152. public PooledConnection getPooledConnection() throws SQLException {
  1153. return getConnection(maxWait);
  1154. }
  1155. @Override
  1156. public PooledConnection getPooledConnection(String user, String password) throws SQLException {
  1157. throw new UnsupportedOperationException("Not supported by DruidDataSource");
  1158. }
  1159. public DruidPooledConnection getConnectionDirect(long maxWaitMillis) throws SQLException {
  1160. int notFullTimeoutRetryCnt = 0;
  1161. for (;;) {
  1162. // handle notFullTimeoutRetry
  1163. DruidPooledConnection poolableConnection;
  1164. try {
  1165. poolableConnection = getConnectionInternal(maxWaitMillis);
  1166. } catch (GetConnectionTimeoutException ex) {
  1167. if (notFullTimeoutRetryCnt <= this.notFullTimeoutRetryCount && !isFull()) {
  1168. notFullTimeoutRetryCnt++;
  1169. if (LOG.isWarnEnabled()) {
  1170. LOG.warn("get connection timeout retry : " + notFullTimeoutRetryCnt);
  1171. }
  1172. continue;
  1173. }
  1174. throw ex;
  1175. }
  1176. if (testOnBorrow) {
  1177. boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
  1178. if (!validate) {
  1179. if (LOG.isDebugEnabled()) {
  1180. LOG.debug("skip not validate connection.");
  1181. }
  1182. Connection realConnection = poolableConnection.conn;
  1183. discardConnection(realConnection);
  1184. continue;
  1185. }
  1186. } else {
  1187. Connection realConnection = poolableConnection.conn;
  1188. if (poolableConnection.conn.isClosed()) {
  1189. discardConnection(null); // 传入null,避免重复关闭
  1190. continue;
  1191. }
  1192. if (testWhileIdle) {
  1193. final DruidConnectionHolder holder = poolableConnection.holder;
  1194. long currentTimeMillis = System.currentTimeMillis();
  1195. long lastActiveTimeMillis = holder.lastActiveTimeMillis;
  1196. long lastKeepTimeMillis = holder.lastKeepTimeMillis;
  1197. if (lastKeepTimeMillis > lastActiveTimeMillis) {
  1198. lastActiveTimeMillis = lastKeepTimeMillis;
  1199. }
  1200. long idleMillis = currentTimeMillis - lastActiveTimeMillis;
  1201. long timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis;
  1202. if (timeBetweenEvictionRunsMillis <= 0) {
  1203. timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
  1204. }
  1205. if (idleMillis >= timeBetweenEvictionRunsMillis
  1206. || idleMillis < 0 // unexcepted branch
  1207. ) {
  1208. boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
  1209. if (!validate) {
  1210. if (LOG.isDebugEnabled()) {
  1211. LOG.debug("skip not validate connection.");
  1212. }
  1213. discardConnection(realConnection);
  1214. continue;
  1215. }
  1216. }
  1217. }
  1218. }
  1219. if (removeAbandoned) {
  1220. StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
  1221. poolableConnection.connectStackTrace = stackTrace;
  1222. poolableConnection.setConnectedTimeNano();
  1223. poolableConnection.traceEnable = true;
  1224. activeConnectionLock.lock();
  1225. try {
  1226. activeConnections.put(poolableConnection, PRESENT);
  1227. } finally {
  1228. activeConnectionLock.unlock();
  1229. }
  1230. }
  1231. if (!this.defaultAutoCommit) {
  1232. poolableConnection.setAutoCommit(false);
  1233. }
  1234. return poolableConnection;
  1235. }
  1236. }
  1237. /**
  1238. * 抛弃连接,不进行回收,而是抛弃
  1239. *
  1240. * @param realConnection
  1241. */
  1242. public void discardConnection(Connection realConnection) {
  1243. JdbcUtils.close(realConnection);
  1244. lock.lock();
  1245. try {
  1246. activeCount--;
  1247. discardCount++;
  1248. if (activeCount <= minIdle) {
  1249. emptySignal();
  1250. }
  1251. } finally {
  1252. lock.unlock();
  1253. }
  1254. }
  1255. private DruidPooledConnection getConnectionInternal(long maxWait) throws SQLException {
  1256. if (closed) {
  1257. connectErrorCountUpdater.incrementAndGet(this);
  1258. throw new DataSourceClosedException("dataSource already closed at " + new Date(closeTimeMillis));
  1259. }
  1260. if (!enable) {
  1261. connectErrorCountUpdater.incrementAndGet(this);
  1262. throw new DataSourceDisableException();
  1263. }
  1264. final long nanos = TimeUnit.MILLISECONDS.toNanos(maxWait);
  1265. final int maxWaitThreadCount = this.maxWaitThreadCount;
  1266. DruidConnectionHolder holder;
  1267. for (boolean createDirect = false;;) {
  1268. if (createDirect) {
  1269. createStartNanosUpdater.set(this, System.nanoTime());
  1270. if (creatingCountUpdater.compareAndSet(this, 0, 1)) {
  1271. PhysicalConnectionInfo pyConnInfo = DruidDataSource.this.createPhysicalConnection();
  1272. holder = new DruidConnectionHolder(this, pyConnInfo);
  1273. holder.lastActiveTimeMillis = System.currentTimeMillis();
  1274. creatingCountUpdater.decrementAndGet(this);
  1275. directCreateCountUpdater.incrementAndGet(this);
  1276. if (LOG.isDebugEnabled()) {
  1277. LOG.debug("conn-direct_create ");
  1278. }
  1279. boolean discard = false;
  1280. lock.lock();
  1281. try {
  1282. if (activeCount < maxActive) {
  1283. activeCount++;
  1284. if (activeCount > activePeak) {
  1285. activePeak = activeCount;
  1286. activePeakTime = System.currentTimeMillis();
  1287. }
  1288. break;
  1289. } else {
  1290. discard = true;
  1291. }
  1292. } finally {
  1293. lock.unlock();
  1294. }
  1295. if (discard) {
  1296. JdbcUtils.close(pyConnInfo.getPhysicalConnection());
  1297. }
  1298. }
  1299. }
  1300. try {
  1301. lock.lockInterruptibly();
  1302. } catch (InterruptedException e) {
  1303. connectErrorCountUpdater.incrementAndGet(this);
  1304. throw new SQLException("interrupt", e);
  1305. }
  1306. try {
  1307. if (maxWaitThreadCount > 0
  1308. && notEmptyWaitThreadCount >= maxWaitThreadCount) {
  1309. connectErrorCountUpdater.incrementAndGet(this);
  1310. throw new SQLException("maxWaitThreadCount " + maxWaitThreadCount + ", current wait Thread count "
  1311. + lock.getQueueLength());
  1312. }
  1313. if (onFatalError
  1314. && onFatalErrorMaxActive > 0
  1315. && activeCount >= onFatalErrorMaxActive) {
  1316. connectErrorCountUpdater.incrementAndGet(this);
  1317. StringBuilder errorMsg = new StringBuilder();
  1318. errorMsg.append("onFatalError, activeCount ")
  1319. .append(activeCount)
  1320. .append(", onFatalErrorMaxActive ")
  1321. .append(onFatalErrorMaxActive);
  1322. if (lastFatalErrorTimeMillis > 0) {
  1323. errorMsg.append(", time '")
  1324. .append(StringUtils.formatDateTime19(
  1325. lastFatalErrorTimeMillis, TimeZone.getDefault()))
  1326. .append("'");
  1327. }
  1328. if (lastFatalErrorSql != null) {
  1329. errorMsg.append(", sql \n")
  1330. .append(lastFatalErrorSql);
  1331. }
  1332. throw new SQLException(
  1333. errorMsg.toString(), lastFatalError);
  1334. }
  1335. connectCount++;
  1336. if (createScheduler != null
  1337. && poolingCount == 0
  1338. && activeCount < maxActive
  1339. && creatingCountUpdater.get(this) == 0
  1340. && createScheduler instanceof ScheduledThreadPoolExecutor) {
  1341. ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) createScheduler;
  1342. if (executor.getQueue().size() > 0) {
  1343. createDirect = true;
  1344. continue;
  1345. }
  1346. }
  1347. if (maxWait > 0) {
  1348. holder = pollLast(nanos);
  1349. } else {
  1350. holder = takeLast();
  1351. }
  1352. if (holder != null) {
  1353. activeCount++;
  1354. if (activeCount > activePeak) {
  1355. activePeak = activeCount;
  1356. activePeakTime = System.currentTimeMillis();
  1357. }
  1358. }
  1359. } catch (InterruptedException e) {
  1360. connectErrorCountUpdater.incrementAndGet(this);
  1361. throw new SQLException(e.getMessage(), e);
  1362. } catch (SQLException e) {
  1363. connectErrorCountUpdater.incrementAndGet(this);
  1364. throw e;
  1365. } finally {
  1366. lock.unlock();
  1367. }
  1368. break;
  1369. }
  1370. if (holder == null) {
  1371. long waitNanos = waitNanosLocal.get();
  1372. StringBuilder buf = new StringBuilder(128);
  1373. buf.append("wait millis ")//
  1374. .append(waitNanos / (1000 * 1000))//
  1375. .append(", active ").append(activeCount)//
  1376. .append(", maxActive ").append(maxActive)//
  1377. .append(", creating ").append(creatingCount)//
  1378. ;
  1379. if (creatingCount > 0 && createStartNanos > 0) {
  1380. long createElapseMillis = (System.nanoTime() - createStartNanos) / (1000 * 1000);
  1381. if (createElapseMillis > 0) {
  1382. buf.append(", createElapseMillis ").append(createElapseMillis);
  1383. }
  1384. }
  1385. if (createErrorCount > 0) {
  1386. buf.append(", createErrorCount ").append(createErrorCount);
  1387. }
  1388. List<JdbcSqlStatValue> sqlList = this.getDataSourceStat().getRuningSqlList();
  1389. for (int i = 0; i < sqlList.size(); ++i) {
  1390. if (i != 0) {
  1391. buf.append('\n');
  1392. } else {
  1393. buf.append(", ");
  1394. }
  1395. JdbcSqlStatValue sql = sqlList.get(i);
  1396. buf.append("runningSqlCount ").append(sql.getRunningCount());
  1397. buf.append(" : ");
  1398. buf.append(sql.getSql());
  1399. }
  1400. String errorMessage = buf.toString();
  1401. if (this.createError != null) {
  1402. throw new GetConnectionTimeoutException(errorMessage, createError);
  1403. } else {
  1404. throw new GetConnectionTimeoutException(errorMessage);
  1405. }
  1406. }
  1407. holder.incrementUseCount();
  1408. DruidPooledConnection poolalbeConnection = new DruidPooledConnection(holder);
  1409. return poolalbeConnection;
  1410. }
  1411. public void handleConnectionException(DruidPooledConnection pooledConnection, Throwable t, String sql) throws SQLException {
  1412. final DruidConnectionHolder holder = pooledConnection.getConnectionHolder();
  1413. errorCountUpdater.incrementAndGet(this);
  1414. lastError = t;
  1415. lastErrorTimeMillis = System.currentTimeMillis();
  1416. if (t instanceof SQLException) {
  1417. SQLException sqlEx = (SQLException) t;
  1418. // broadcastConnectionError
  1419. ConnectionEvent event = new ConnectionEvent(pooledConnection, sqlEx);
  1420. for (ConnectionEventListener eventListener : holder.getConnectionEventListeners()) {
  1421. eventListener.connectionErrorOccurred(event);
  1422. }
  1423. // exceptionSorter.isExceptionFatal
  1424. if (exceptionSorter != null && exceptionSorter.isExceptionFatal(sqlEx)) {
  1425. handleFatalError(pooledConnection, sqlEx, sql);
  1426. }
  1427. throw sqlEx;
  1428. } else {
  1429. throw new SQLException("Error", t);
  1430. }
  1431. }
  1432. protected final void handleFatalError(DruidPooledConnection conn, SQLException error, String sql) throws SQLException {
  1433. final DruidConnectionHolder holder = conn.holder;
  1434. if (conn.isTraceEnable()) {
  1435. activeConnectionLock.lock();
  1436. try {
  1437. if (conn.isTraceEnable()) {
  1438. activeConnections.remove(conn);
  1439. conn.setTraceEnable(false);
  1440. }
  1441. } finally {
  1442. activeConnectionLock.unlock();
  1443. }
  1444. }
  1445. long lastErrorTimeMillis = this.lastErrorTimeMillis;
  1446. if (lastErrorTimeMillis == 0) {
  1447. lastErrorTimeMillis = System.currentTimeMillis();
  1448. }
  1449. if (sql != null && sql.length() > 1024) {
  1450. sql = sql.substring(0, 1024);
  1451. }
  1452. boolean requireDiscard = false;
  1453. final ReentrantLock lock = conn.lock;
  1454. lock.lock();
  1455. try {
  1456. if ((!conn.isClosed()) || !conn.isDisable()) {
  1457. holder.setDiscard(true);
  1458. conn.disable(error);
  1459. requireDiscard = true;
  1460. }
  1461. lastFatalErrorTimeMillis = lastErrorTimeMillis;
  1462. onFatalError = true;
  1463. lastFatalError = error;
  1464. lastFatalErrorSql = sql;
  1465. } finally {
  1466. lock.unlock();
  1467. }
  1468. if (requireDiscard) {
  1469. if (holder.statementTrace != null) {
  1470. holder.lock.lock();
  1471. try {
  1472. for (Statement stmt : holder.statementTrace) {
  1473. JdbcUtils.close(stmt);
  1474. }
  1475. } finally {
  1476. holder.lock.unlock();
  1477. }
  1478. }
  1479. this.discardConnection(holder.getConnection());
  1480. holder.setDiscard(true);
  1481. }
  1482. LOG.error("discard connection", error);
  1483. }
  1484. /**
  1485. * 回收连接
  1486. */
  1487. protected void recycle(DruidPooledConnection pooledConnection) throws SQLException {
  1488. final DruidConnectionHolder holder = pooledConnection.holder;
  1489. if (holder == null) {
  1490. LOG.warn("connectionHolder is null");
  1491. return;
  1492. }
  1493. if (logDifferentThread //
  1494. && (!isAsyncCloseConnectionEnable()) //
  1495. && pooledConnection.ownerThread != Thread.currentThread()//
  1496. ) {
  1497. LOG.warn("get/close not same thread");
  1498. }
  1499. final Connection physicalConnection = holder.conn;
  1500. if (pooledConnection.traceEnable) {
  1501. Object oldInfo = null;
  1502. activeConnectionLock.lock();
  1503. try {
  1504. if (pooledConnection.traceEnable) {
  1505. oldInfo = activeConnections.remove(pooledConnection);
  1506. pooledConnection.traceEnable = false;
  1507. }
  1508. } finally {
  1509. activeConnectionLock.unlock();
  1510. }
  1511. if (oldInfo == null) {
  1512. if (LOG.isWarnEnabled()) {
  1513. LOG.warn("remove abandonded failed. activeConnections.size " + activeConnections.size());
  1514. }
  1515. }
  1516. }
  1517. final boolean isAutoCommit = holder.underlyingAutoCommit;
  1518. final boolean isReadOnly = holder.underlyingReadOnly;
  1519. final boolean testOnReturn = this.testOnReturn;
  1520. try {
  1521. // check need to rollback?
  1522. if ((!isAutoCommit) && (!isReadOnly)) {
  1523. pooledConnection.rollback();
  1524. }
  1525. // reset holder, restore default settings, clear warnings
  1526. boolean isSameThread = pooledConnection.ownerThread == Thread.currentThread();
  1527. if (!isSameThread) {
  1528. final ReentrantLock lock = pooledConnection.lock;
  1529. lock.lock();
  1530. try {
  1531. holder.reset();
  1532. } finally {
  1533. lock.unlock();
  1534. }
  1535. } else {
  1536. holder.reset();
  1537. }
  1538. if (holder.discard) {
  1539. return;
  1540. }
  1541. if (phyMaxUseCount > 0 && holder.useCount >= phyMaxUseCount) {
  1542. discardConnection(holder.conn);
  1543. return;
  1544. }
  1545. if (physicalConnection.isClosed()) {
  1546. lock.lock();
  1547. try {
  1548. activeCount--;
  1549. closeCount++;
  1550. } finally {
  1551. lock.unlock();
  1552. }
  1553. return;
  1554. }
  1555. if (testOnReturn) {
  1556. boolean validate = testConnectionInternal(holder, physicalConnection);
  1557. if (!validate) {
  1558. JdbcUtils.close(physicalConnection);
  1559. destroyCountUpdater.incrementAndGet(this);
  1560. lock.lock();
  1561. try {
  1562. activeCount--;
  1563. closeCount++;
  1564. } finally {
  1565. lock.unlock();
  1566. }
  1567. return;
  1568. }
  1569. }
  1570. if (!enable) {
  1571. discardConnection(holder.conn);
  1572. return;
  1573. }
  1574. boolean result;
  1575. final long currentTimeMillis = System.currentTimeMillis();
  1576. if (phyTimeoutMillis > 0) {
  1577. long phyConnectTimeMillis = currentTimeMillis - holder.connectTimeMillis;
  1578. if (phyConnectTimeMillis > phyTimeoutMillis) {
  1579. discardConnection(holder.conn);
  1580. return;
  1581. }
  1582. }
  1583. lock.lock();
  1584. try {
  1585. activeCount--;
  1586. closeCount++;
  1587. result = putLast(holder, currentTimeMillis);
  1588. recycleCount++;
  1589. } finally {
  1590. lock.unlock();
  1591. }
  1592. if (!result) {
  1593. JdbcUtils.close(holder.conn);
  1594. LOG.info("connection recyle failed.");
  1595. }
  1596. } catch (Throwable e) {
  1597. holder.clearStatementCache();
  1598. if (!holder.discard) {
  1599. this.discardConnection(physicalConnection);
  1600. holder.discard = true;
  1601. }
  1602. LOG.error("recyle error", e);
  1603. recycleErrorCountUpdater.incrementAndGet(this);
  1604. }
  1605. }
  1606. public long getRecycleErrorCount() {
  1607. return recycleErrorCount;
  1608. }
  1609. public void clearStatementCache() throws SQLException {
  1610. lock.lock();
  1611. try {
  1612. for (int i = 0; i < poolingCount; ++i) {
  1613. DruidConnectionHolder conn = connections[i];
  1614. if (conn.statementPool != null) {
  1615. conn.statementPool.clear();
  1616. }
  1617. }
  1618. } finally {
  1619. lock.unlock();
  1620. }
  1621. }
  1622. /**
  1623. * close datasource
  1624. */
  1625. public void close() {
  1626. if (LOG.isInfoEnabled()) {
  1627. LOG.info("{dataSource-" + this.getID() + "} closing ...");
  1628. }
  1629. lock.lock();
  1630. try {
  1631. if (this.closed) {
  1632. return;
  1633. }
  1634. if (!this.inited) {
  1635. return;
  1636. }
  1637. this.closing = true;
  1638. if (logStatsThread != null) {
  1639. logStatsThread.interrupt();
  1640. }
  1641. if (createConnectionThread != null) {
  1642. createConnectionThread.interrupt();
  1643. }
  1644. if (destroyConnectionThread != null) {
  1645. destroyConnectionThread.interrupt();
  1646. }
  1647. if (createSchedulerFuture != null) {
  1648. createSchedulerFuture.cancel(true);
  1649. }
  1650. if (destroySchedulerFuture != null) {
  1651. destroySchedulerFuture.cancel(true);
  1652. }
  1653. for (int i = 0; i < poolingCount; ++i) {
  1654. DruidConnectionHolder connHolder = connections[i];
  1655. for (PreparedStatementHolder stmtHolder : connHolder.getStatementPool().getMap().values()) {
  1656. connHolder.getStatementPool().closeRemovedStatement(stmtHolder);
  1657. }
  1658. connHolder.getStatementPool().getMap().clear();
  1659. Connection physicalConnection = connHolder.getConnection();
  1660. try {
  1661. physicalConnection.close();
  1662. } catch (Exception ex) {
  1663. LOG.warn("close connection error", ex);
  1664. }
  1665. connections[i] = null;
  1666. destroyCountUpdater.incrementAndGet(this);
  1667. }
  1668. poolingCount = 0;
  1669. unregisterMbean();
  1670. enable = false;
  1671. notEmpty.signalAll();
  1672. notEmptySignalCount++;
  1673. this.closed = true;
  1674. this.closeTimeMillis = System.currentTimeMillis();
  1675. for (Filter filter : filters) {
  1676. filter.destroy();
  1677. }
  1678. } finally {
  1679. lock.unlock();
  1680. }
  1681. if (LOG.isInfoEnabled()) {
  1682. LOG.info("{dataSource-" + this.getID() + "} closed");
  1683. }
  1684. }
  1685. public void registerMbean() {
  1686. if (!mbeanRegistered) {
  1687. AccessController.doPrivileged(new PrivilegedAction<Object>() {
  1688. @Override
  1689. public Object run() {
  1690. ObjectName objectName = DruidDataSourceStatManager.addDataSource(DruidDataSource.this,
  1691. DruidDataSource.this.name);
  1692. DruidDataSource.this.setObjectName(objectName);
  1693. DruidDataSource.this.mbeanRegistered = true;
  1694. return null;
  1695. }
  1696. });
  1697. }
  1698. }
  1699. public void unregisterMbean() {
  1700. if (mbeanRegistered) {
  1701. AccessController.doPrivileged(new PrivilegedAction<Object>() {
  1702. @Override
  1703. public Object run() {
  1704. DruidDataSourceStatManager.removeDataSource(DruidDataSource.this);
  1705. DruidDataSource.this.mbeanRegistered = false;
  1706. return null;
  1707. }
  1708. });
  1709. }
  1710. }
  1711. public boolean isMbeanRegistered() {
  1712. return mbeanRegistered;
  1713. }
  1714. boolean putLast(DruidConnectionHolder e, long lastActiveTimeMillis) {
  1715. if (poolingCount >= maxActive) {
  1716. return false;
  1717. }
  1718. e.lastActiveTimeMillis = lastActiveTimeMillis;
  1719. connections[poolingCount] = e;
  1720. incrementPoolingCount();
  1721. if (poolingCount > poolingPeak) {
  1722. poolingPeak = poolingCount;
  1723. poolingPeakTime = lastActiveTimeMillis;
  1724. }
  1725. notEmpty.signal();
  1726. notEmptySignalCount++;
  1727. return true;
  1728. }
  1729. DruidConnectionHolder takeLast() throws InterruptedException, SQLException {
  1730. try {
  1731. while (poolingCount == 0) {
  1732. emptySignal(); // send signal to CreateThread create connection
  1733. if (failFast && isFailContinuous()) {
  1734. throw new DataSourceNotAvailableException(createError);
  1735. }
  1736. notEmptyWaitThreadCount++;
  1737. if (notEmptyWaitThreadCount > notEmptyWaitThreadPeak) {
  1738. notEmptyWaitThreadPeak = notEmptyWaitThreadCount;
  1739. }
  1740. try {
  1741. notEmpty.await(); // signal by recycle or creator
  1742. } finally {
  1743. notEmptyWaitThreadCount--;
  1744. }
  1745. notEmptyWaitCount++;
  1746. if (!enable) {
  1747. connectErrorCountUpdater.incrementAndGet(this);
  1748. throw new DataSourceDisableException();
  1749. }
  1750. }
  1751. } catch (InterruptedException ie) {
  1752. notEmpty.signal(); // propagate to non-interrupted thread
  1753. notEmptySignalCount++;
  1754. throw ie;
  1755. }
  1756. decrementPoolingCount();
  1757. DruidConnectionHolder last = connections[poolingCount];
  1758. connections[poolingCount] = null;
  1759. return last;
  1760. }
  1761. private DruidConnectionHolder pollLast(long nanos) throws InterruptedException, SQLException {
  1762. long estimate = nanos;
  1763. for (;;) {
  1764. if (poolingCount == 0) {
  1765. emptySignal(); // send signal to CreateThread create connection
  1766. if (failFast && isFailContinuous()) {
  1767. throw new DataSourceNotAvailableException(createError);
  1768. }
  1769. if (estimate <= 0) {
  1770. waitNanosLocal.set(nanos - estimate);
  1771. return null;
  1772. }
  1773. notEmptyWaitThreadCount++;
  1774. if (notEmptyWaitThreadCount > notEmptyWaitThreadPeak) {
  1775. notEmptyWaitThreadPeak = notEmptyWaitThreadCount;
  1776. }
  1777. try {
  1778. long startEstimate = estimate;
  1779. estimate = notEmpty.awaitNanos(estimate); // signal by
  1780. // recycle or
  1781. // creator
  1782. notEmptyWaitCount++;
  1783. notEmptyWaitNanos += (startEstimate - estimate);
  1784. if (!enable) {
  1785. connectErrorCountUpdater.incrementAndGet(this);
  1786. throw new DataSourceDisableException();
  1787. }
  1788. } catch (InterruptedException ie) {
  1789. notEmpty.signal(); // propagate to non-interrupted thread
  1790. notEmptySignalCount++;
  1791. throw ie;
  1792. } finally {
  1793. notEmptyWaitThreadCount--;
  1794. }
  1795. if (poolingCount == 0) {
  1796. if (estimate > 0) {
  1797. continue;
  1798. }
  1799. waitNanosLocal.set(nanos - estimate);
  1800. return null;
  1801. }
  1802. }
  1803. decrementPoolingCount();
  1804. DruidConnectionHolder last = connections[poolingCount];
  1805. connections[poolingCount] = null;
  1806. long waitNanos = nanos - estimate;
  1807. last.setLastNotEmptyWaitNanos(waitNanos);
  1808. return last;
  1809. }
  1810. }
  1811. private final void decrementPoolingCount() {
  1812. poolingCount--;
  1813. }
  1814. private final void incrementPoolingCount() {
  1815. poolingCount++;
  1816. }
  1817. @Override
  1818. public Connection getConnection(String username, String password) throws SQLException {
  1819. if (this.username == null
  1820. && this.password == null
  1821. && username != null
  1822. && password != null) {
  1823. this.username = username;
  1824. this.password = password;
  1825. return getConnection();
  1826. }
  1827. if (!StringUtils.equals(username, this.username)) {
  1828. throw new UnsupportedOperationException("Not supported by DruidDataSource");
  1829. }
  1830. if (!StringUtils.equals(password, this.password)) {
  1831. throw new UnsupportedOperationException("Not supported by DruidDataSource");
  1832. }
  1833. return getConnection();
  1834. }
  1835. public long getCreateCount() {
  1836. return createCount;
  1837. }
  1838. public long getDestroyCount() {
  1839. return destroyCount;
  1840. }
  1841. public long getConnectCount() {
  1842. lock.lock();
  1843. try {
  1844. return connectCount;
  1845. } finally {
  1846. lock.unlock();
  1847. }
  1848. }
  1849. public long getCloseCount() {
  1850. return closeCount;
  1851. }
  1852. public long getConnectErrorCount() {
  1853. return connectErrorCountUpdater.get(this);
  1854. }
  1855. @Override
  1856. public int getPoolingCount() {
  1857. lock.lock();
  1858. try {
  1859. return poolingCount;
  1860. } finally {
  1861. lock.unlock();
  1862. }
  1863. }
  1864. public int getPoolingPeak() {
  1865. lock.lock();
  1866. try {
  1867. return poolingPeak;
  1868. } finally {
  1869. lock.unlock();
  1870. }
  1871. }
  1872. public Date getPoolingPeakTime() {
  1873. if (poolingPeakTime <= 0) {
  1874. return null;
  1875. }
  1876. return new Date(poolingPeakTime);
  1877. }
  1878. public long getRecycleCount() {
  1879. return recycleCount;
  1880. }
  1881. public int getActiveCount() {
  1882. lock.lock();
  1883. try {
  1884. return activeCount;
  1885. } finally {
  1886. lock.unlock();
  1887. }
  1888. }
  1889. public void logStats() {
  1890. final DruidDataSourceStatLogger statLogger = this.statLogger;
  1891. if (statLogger == null) {
  1892. return;
  1893. }
  1894. DruidDataSourceStatValue statValue = getStatValueAndReset();
  1895. statLogger.log(statValue);
  1896. }
  1897. public DruidDataSourceStatValue getStatValueAndReset() {
  1898. DruidDataSourceStatValue value = new DruidDataSourceStatValue();
  1899. lock.lock();
  1900. try {
  1901. value.setPoolingCount(this.poolingCount);
  1902. value.setPoolingPeak(this.poolingPeak);
  1903. value.setPoolingPeakTime(this.poolingPeakTime);
  1904. value.setActiveCount(this.activeCount);
  1905. value.setActivePeak(this.activePeak);
  1906. value.setActivePeakTime(this.activePeakTime);
  1907. value.setConnectCount(this.connectCount);
  1908. value.setCloseCount(this.closeCount);
  1909. value.setWaitThreadCount(lock.getWaitQueueLength(notEmpty));
  1910. value.setNotEmptyWaitCount(this.notEmptyWaitCount);
  1911. value.setNotEmptyWaitNanos(this.notEmptyWaitNanos);
  1912. value.setKeepAliveCheckCount(this.keepAliveCheckCount);
  1913. // reset
  1914. this.poolingPeak = 0;
  1915. this.poolingPeakTime = 0;
  1916. this.activePeak = 0;
  1917. this.activePeakTime = 0;
  1918. this.connectCount = 0;
  1919. this.closeCount = 0;
  1920. this.keepAliveCheckCount = 0;
  1921. this.notEmptyWaitCount = 0;
  1922. this.notEmptyWaitNanos = 0;
  1923. } finally {
  1924. lock.unlock();
  1925. }
  1926. value.setName(this.getName());
  1927. value.setDbType(this.dbType);
  1928. value.setDriverClassName(this.getDriverClassName());
  1929. value.setUrl(this.getUrl());
  1930. value.setUserName(this.getUsername());
  1931. value.setFilterClassNames(this.getFilterClassNames());
  1932. value.setInitialSize(this.getInitialSize());
  1933. value.setMinIdle(this.getMinIdle());
  1934. value.setMaxActive(this.getMaxActive());
  1935. value.setQueryTimeout(this.getQueryTimeout());
  1936. value.setTransactionQueryTimeout(this.getTransactionQueryTimeout());
  1937. value.setLoginTimeout(this.getLoginTimeout());
  1938. value.setValidConnectionCheckerClassName(this.getValidConnectionCheckerClassName());
  1939. value.setExceptionSorterClassName(this.getExceptionSorterClassName());
  1940. value.setTestOnBorrow(this.testOnBorrow);
  1941. value.setTestOnReturn(this.testOnReturn);
  1942. value.setTestWhileIdle(this.testWhileIdle);
  1943. value.setDefaultAutoCommit(this.isDefaultAutoCommit());
  1944. if (defaultReadOnly != null) {
  1945. value.setDefaultReadOnly(defaultReadOnly);
  1946. }
  1947. value.setDefaultTransactionIsolation(this.getDefaultTransactionIsolation());
  1948. value.setLogicConnectErrorCount(connectErrorCountUpdater.getAndSet(this, 0));
  1949. value.setPhysicalConnectCount(createCountUpdater.getAndSet(this, 0));
  1950. value.setPhysicalCloseCount(destroyCountUpdater.getAndSet(this, 0));
  1951. value.setPhysicalConnectErrorCount(createErrorCountUpdater.getAndSet(this, 0));
  1952. value.setExecuteCount(this.getAndResetExecuteCount());
  1953. value.setErrorCount(errorCountUpdater.getAndSet(this, 0));
  1954. value.setCommitCount(commitCountUpdater.getAndSet(this, 0));
  1955. value.setRollbackCount(rollbackCountUpdater.getAndSet(this, 0));
  1956. value.setPstmtCacheHitCount(cachedPreparedStatementHitCountUpdater.getAndSet(this,0));
  1957. value.setPstmtCacheMissCount(cachedPreparedStatementMissCountUpdater.getAndSet(this, 0));
  1958. value.setStartTransactionCount(startTransactionCountUpdater.getAndSet(this, 0));
  1959. value.setTransactionHistogram(this.getTransactionHistogram().toArrayAndReset());
  1960. value.setConnectionHoldTimeHistogram(this.getDataSourceStat().getConnectionHoldHistogram().toArrayAndReset());
  1961. value.setRemoveAbandoned(this.isRemoveAbandoned());
  1962. value.setClobOpenCount(this.getDataSourceStat().getClobOpenCountAndReset());
  1963. value.setBlobOpenCount(this.getDataSourceStat().getBlobOpenCountAndReset());
  1964. value.setSqlSkipCount(this.getDataSourceStat().getSkipSqlCountAndReset());
  1965. value.setSqlList(this.getDataSourceStat().getSqlStatMapAndReset());
  1966. return value;
  1967. }
  1968. public long getRemoveAbandonedCount() {
  1969. return removeAbandonedCount;
  1970. }
  1971. protected boolean put(PhysicalConnectionInfo physicalConnectionInfo) {
  1972. DruidConnectionHolder holder = null;
  1973. try {
  1974. holder = new DruidConnectionHolder(DruidDataSource.this, physicalConnectionInfo);
  1975. } catch (SQLException ex) {
  1976. lock.lock();
  1977. try {
  1978. if (createScheduler != null) {
  1979. createTaskCount--;
  1980. }
  1981. } finally {
  1982. lock.unlock();
  1983. }
  1984. LOG.error("create connection holder error", ex);
  1985. return false;
  1986. }
  1987. return put(holder);
  1988. }
  1989. private boolean put(DruidConnectionHolder holder) {
  1990. lock.lock();
  1991. try {
  1992. if (poolingCount >= maxActive) {
  1993. return false;
  1994. }
  1995. connections[poolingCount] = holder;
  1996. incrementPoolingCount();
  1997. if (poolingCount > poolingPeak) {
  1998. poolingPeak = poolingCount;
  1999. poolingPeakTime = System.currentTimeMillis();
  2000. }
  2001. notEmpty.signal();
  2002. notEmptySignalCount++;
  2003. if (createScheduler != null) {
  2004. createTaskCount--;
  2005. if (poolingCount + createTaskCount < notEmptyWaitThreadCount //
  2006. && activeCount + poolingCount + createTaskCount < maxActive) {
  2007. emptySignal();
  2008. }
  2009. }
  2010. } finally {
  2011. lock.unlock();
  2012. }
  2013. return true;
  2014. }
  2015. public class CreateConnectionTask implements Runnable {
  2016. private int errorCount = 0;
  2017. private boolean initTask = false;
  2018. public CreateConnectionTask() {
  2019. }
  2020. public CreateConnectionTask(boolean initTask) {
  2021. this.initTask = initTask;
  2022. }
  2023. @Override
  2024. public void run() {
  2025. runInternal();
  2026. }
  2027. private void runInternal() {
  2028. for (;;) {
  2029. // addLast
  2030. lock.lock();
  2031. try {
  2032. if (closed || closing) {
  2033. createTaskCount--;
  2034. return;
  2035. }
  2036. boolean emptyWait = true;
  2037. if (createError != null && poolingCount == 0) {
  2038. emptyWait = false;
  2039. }
  2040. if (emptyWait) {
  2041. // 必须存在线程等待,才创建连接
  2042. if (poolingCount >= notEmptyWaitThreadCount //
  2043. && (!(keepAlive && activeCount + poolingCount < minIdle))
  2044. && (!initTask)
  2045. && !isFailContinuous()
  2046. ) {
  2047. createTaskCount--;
  2048. return;
  2049. }
  2050. // 防止创建超过maxActive数量的连接
  2051. if (activeCount + poolingCount >= maxActive) {
  2052. createTaskCount--;
  2053. return;
  2054. }
  2055. }
  2056. } finally {
  2057. lock.unlock();
  2058. }
  2059. PhysicalConnectionInfo physicalConnection = null;
  2060. try {
  2061. physicalConnection = createPhysicalConnection();
  2062. } catch (OutOfMemoryError e) {
  2063. LOG.error("create connection OutOfMemoryError, out memory. ", e);
  2064. errorCount++;
  2065. if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) {
  2066. // fail over retry attempts
  2067. setFailContinuous(true);
  2068. if (failFast) {
  2069. lock.lock();
  2070. try {
  2071. notEmpty.signalAll();
  2072. } finally {
  2073. lock.unlock();
  2074. }
  2075. }
  2076. if (breakAfterAcquireFailure) {
  2077. lock.lock();
  2078. try {
  2079. createTaskCount--;
  2080. } finally {
  2081. lock.unlock();
  2082. }
  2083. return;
  2084. }
  2085. this.errorCount = 0; // reset errorCount
  2086. if (closing || closed) {
  2087. createTaskCount--;
  2088. return;
  2089. }
  2090. createSchedulerFuture = createScheduler.schedule(this, timeBetweenConnectErrorMillis, TimeUnit.MILLISECONDS);
  2091. return;
  2092. }
  2093. } catch (SQLException e) {
  2094. LOG.error("create connection SQLException, url: " + jdbcUrl, e);
  2095. errorCount++;
  2096. if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) {
  2097. // fail over retry attempts
  2098. setFailContinuous(true);
  2099. if (failFast) {
  2100. lock.lock();
  2101. try {
  2102. notEmpty.signalAll();
  2103. } finally {
  2104. lock.unlock();
  2105. }
  2106. }
  2107. if (breakAfterAcquireFailure) {
  2108. lock.lock();
  2109. try {
  2110. createTaskCount--;
  2111. } finally {
  2112. lock.unlock();
  2113. }
  2114. return;
  2115. }
  2116. this.errorCount = 0; // reset errorCount
  2117. if (closing || closed) {
  2118. createTaskCount--;
  2119. return;
  2120. }
  2121. createSchedulerFuture = createScheduler.schedule(this, timeBetweenConnectErrorMillis, TimeUnit.MILLISECONDS);
  2122. return;
  2123. }
  2124. } catch (RuntimeException e) {
  2125. LOG.error("create connection RuntimeException", e);
  2126. // unknow fatal exception
  2127. setFailContinuous(true);
  2128. continue;
  2129. } catch (Error e) {
  2130. lock.lock();
  2131. try {
  2132. createTaskCount--;
  2133. } finally {
  2134. lock.unlock();
  2135. }
  2136. LOG.error("create connection Error", e);
  2137. // unknow fatal exception
  2138. setFailContinuous(true);
  2139. break;
  2140. } catch (Throwable e) {
  2141. LOG.error("create connection unexecpted error.", e);
  2142. break;
  2143. }
  2144. if (physicalConnection == null) {
  2145. continue;
  2146. }
  2147. boolean result = put(physicalConnection);
  2148. if (!result) {
  2149. JdbcUtils.close(physicalConnection.getPhysicalConnection());
  2150. LOG.info("put physical connection to pool failed.");
  2151. }
  2152. break;
  2153. }
  2154. }
  2155. }
  2156. public class CreateConnectionThread extends Thread {
  2157. public CreateConnectionThread(String name){
  2158. super(name);
  2159. this.setDaemon(true);
  2160. }
  2161. public void run() {
  2162. initedLatch.countDown();
  2163. long lastDiscardCount = 0;
  2164. int errorCount = 0;
  2165. for (;;) {
  2166. // addLast
  2167. try {
  2168. lock.lockInterruptibly();
  2169. } catch (InterruptedException e2) {
  2170. break;
  2171. }
  2172. long discardCount = DruidDataSource.this.discardCount;
  2173. boolean discardChanged = discardCount - lastDiscardCount > 0;
  2174. lastDiscardCount = discardCount;
  2175. try {
  2176. boolean emptyWait = true;
  2177. if (createError != null
  2178. && poolingCount == 0
  2179. && !discardChanged) {
  2180. emptyWait = false;
  2181. }
  2182. if (emptyWait
  2183. && asyncInit && createCount < initialSize) {
  2184. emptyWait = false;
  2185. }
  2186. if (emptyWait) {
  2187. // 必须存在线程等待,才创建连接
  2188. if (poolingCount >= notEmptyWaitThreadCount //
  2189. && (!(keepAlive && activeCount + poolingCount < minIdle))
  2190. && !isFailContinuous()
  2191. ) {
  2192. empty.await();
  2193. }
  2194. // 防止创建超过maxActive数量的连接
  2195. if (activeCount + poolingCount >= maxActive) {
  2196. empty.await();
  2197. continue;
  2198. }
  2199. }
  2200. } catch (InterruptedException e) {
  2201. lastCreateError = e;
  2202. lastErrorTimeMillis = System.currentTimeMillis();
  2203. if (!closing) {
  2204. LOG.error("create connection Thread Interrupted, url: " + jdbcUrl, e);
  2205. }
  2206. break;
  2207. } finally {
  2208. lock.unlock();
  2209. }
  2210. PhysicalConnectionInfo connection = null;
  2211. try {
  2212. connection = createPhysicalConnection();
  2213. } catch (SQLException e) {
  2214. LOG.error("create connection SQLException, url: " + jdbcUrl + ", errorCode " + e.getErrorCode()
  2215. + ", state " + e.getSQLState(), e);
  2216. errorCount++;
  2217. if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) {
  2218. // fail over retry attempts
  2219. setFailContinuous(true);
  2220. if (failFast) {
  2221. lock.lock();
  2222. try {
  2223. notEmpty.signalAll();
  2224. } finally {
  2225. lock.unlock();
  2226. }
  2227. }
  2228. if (breakAfterAcquireFailure) {
  2229. break;
  2230. }
  2231. try {
  2232. Thread.sleep(timeBetweenConnectErrorMillis);
  2233. } catch (InterruptedException interruptEx) {
  2234. break;
  2235. }
  2236. }
  2237. } catch (RuntimeException e) {
  2238. LOG.error("create connection RuntimeException", e);
  2239. setFailContinuous(true);
  2240. continue;
  2241. } catch (Error e) {
  2242. LOG.error("create connection Error", e);
  2243. setFailContinuous(true);
  2244. break;
  2245. }
  2246. if (connection == null) {
  2247. continue;
  2248. }
  2249. boolean result = put(connection);
  2250. if (!result) {
  2251. JdbcUtils.close(connection.getPhysicalConnection());
  2252. LOG.info("put physical connection to pool failed.");
  2253. }
  2254. errorCount = 0; // reset errorCount
  2255. }
  2256. }
  2257. }
  2258. public class DestroyConnectionThread extends Thread {
  2259. public DestroyConnectionThread(String name){
  2260. super(name);
  2261. this.setDaemon(true);
  2262. }
  2263. public void run() {
  2264. initedLatch.countDown();
  2265. for (;;) {
  2266. // 从前面开始删除
  2267. try {
  2268. if (closed) {
  2269. break;
  2270. }
  2271. if (timeBetweenEvictionRunsMillis > 0) {
  2272. Thread.sleep(timeBetweenEvictionRunsMillis);
  2273. } else {
  2274. Thread.sleep(1000); //
  2275. }
  2276. if (Thread.interrupted()) {
  2277. break;
  2278. }
  2279. destroyTask.run();
  2280. } catch (InterruptedException e) {
  2281. break;
  2282. }
  2283. }
  2284. }
  2285. }
  2286. public class DestroyTask implements Runnable {
  2287. public DestroyTask() {
  2288. }
  2289. @Override
  2290. public void run() {
  2291. shrink(true, keepAlive);
  2292. if (isRemoveAbandoned()) {
  2293. removeAbandoned();
  2294. }
  2295. }
  2296. }
  2297. public class LogStatsThread extends Thread {
  2298. public LogStatsThread(String name){
  2299. super(name);
  2300. this.setDaemon(true);
  2301. }
  2302. public void run() {
  2303. try {
  2304. for (;;) {
  2305. try {
  2306. logStats();
  2307. } catch (Exception e) {
  2308. LOG.error("logStats error", e);
  2309. }
  2310. Thread.sleep(timeBetweenLogStatsMillis);
  2311. }
  2312. } catch (InterruptedException e) {
  2313. // skip
  2314. }
  2315. }
  2316. }
  2317. public int removeAbandoned() {
  2318. int removeCount = 0;
  2319. long currrentNanos = System.nanoTime();
  2320. List<DruidPooledConnection> abandonedList = new ArrayList<DruidPooledConnection>();
  2321. activeConnectionLock.lock();
  2322. try {
  2323. Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator();
  2324. for (; iter.hasNext();) {
  2325. DruidPooledConnection pooledConnection = iter.next();
  2326. if (pooledConnection.isRunning()) {
  2327. continue;
  2328. }
  2329. long timeMillis = (currrentNanos - pooledConnection.getConnectedTimeNano()) / (1000 * 1000);
  2330. if (timeMillis >= removeAbandonedTimeoutMillis) {
  2331. iter.remove();
  2332. pooledConnection.setTraceEnable(false);
  2333. abandonedList.add(pooledConnection);
  2334. }
  2335. }
  2336. } finally {
  2337. activeConnectionLock.unlock();
  2338. }
  2339. if (abandonedList.size() > 0) {
  2340. for (DruidPooledConnection pooledConnection : abandonedList) {
  2341. final ReentrantLock lock = pooledConnection.lock;
  2342. lock.lock();
  2343. try {
  2344. if (pooledConnection.isDisable()) {
  2345. continue;
  2346. }
  2347. } finally {
  2348. lock.unlock();
  2349. }
  2350. JdbcUtils.close(pooledConnection);
  2351. pooledConnection.abandond();
  2352. removeAbandonedCount++;
  2353. removeCount++;
  2354. if (isLogAbandoned()) {
  2355. StringBuilder buf = new StringBuilder();
  2356. buf.append("abandon connection, owner thread: ");
  2357. buf.append(pooledConnection.getOwnerThread().getName());
  2358. buf.append(", connected at : ");
  2359. buf.append(pooledConnection.getConnectedTimeMillis());
  2360. buf.append(", open stackTrace\n");
  2361. StackTraceElement[] trace = pooledConnection.getConnectStackTrace();
  2362. for (int i = 0; i < trace.length; i++) {
  2363. buf.append("\tat ");
  2364. buf.append(trace[i].toString());
  2365. buf.append("\n");
  2366. }
  2367. buf.append("ownerThread current state is " + pooledConnection.getOwnerThread().getState()
  2368. + ", current stackTrace\n");
  2369. trace = pooledConnection.getOwnerThread().getStackTrace();
  2370. for (int i = 0; i < trace.length; i++) {
  2371. buf.append("\tat ");
  2372. buf.append(trace[i].toString());
  2373. buf.append("\n");
  2374. }
  2375. LOG.error(buf.toString());
  2376. }
  2377. }
  2378. }
  2379. return removeCount;
  2380. }
  2381. /** Instance key */
  2382. protected String instanceKey = null;
  2383. public Reference getReference() throws NamingException {
  2384. final String className = getClass().getName();
  2385. final String factoryName = className + "Factory"; // XXX: not robust
  2386. Reference ref = new Reference(className, factoryName, null);
  2387. ref.add(new StringRefAddr("instanceKey", instanceKey));
  2388. ref.add(new StringRefAddr("url", this.getUrl()));
  2389. ref.add(new StringRefAddr("username", this.getUsername()));
  2390. ref.add(new StringRefAddr("password", this.getPassword()));
  2391. // TODO ADD OTHER PROPERTIES
  2392. return ref;
  2393. }
  2394. @Override
  2395. public List<String> getFilterClassNames() {
  2396. List<String> names = new ArrayList<String>();
  2397. for (Filter filter : filters) {
  2398. names.add(filter.getClass().getName());
  2399. }
  2400. return names;
  2401. }
  2402. public int getRawDriverMajorVersion() {
  2403. int version = -1;
  2404. if (this.driver != null) {
  2405. version = driver.getMajorVersion();
  2406. }
  2407. return version;
  2408. }
  2409. public int getRawDriverMinorVersion() {
  2410. int version = -1;
  2411. if (this.driver != null) {
  2412. version = driver.getMinorVersion();
  2413. }
  2414. return version;
  2415. }
  2416. public String getProperties() {
  2417. Properties properties = new Properties();
  2418. properties.putAll(connectProperties);
  2419. if (properties.containsKey("password")) {
  2420. properties.put("password", "******");
  2421. }
  2422. return properties.toString();
  2423. }
  2424. @Override
  2425. public void shrink() {
  2426. shrink(false, false);
  2427. }
  2428. public void shrink(boolean checkTime) {
  2429. shrink(checkTime, keepAlive);
  2430. }
  2431. public void shrink(boolean checkTime, boolean keepAlive) {
  2432. try {
  2433. lock.lockInterruptibly();
  2434. } catch (InterruptedException e) {
  2435. return;
  2436. }
  2437. int evictCount = 0;
  2438. int keepAliveCount = 0;
  2439. try {
  2440. if (!inited) {
  2441. return;
  2442. }
  2443. final int checkCount = poolingCount - minIdle;
  2444. final long currentTimeMillis = System.currentTimeMillis();
  2445. for (int i = 0; i < poolingCount; ++i) {
  2446. DruidConnectionHolder connection = connections[i];
  2447. if (checkTime) {
  2448. if (phyTimeoutMillis > 0) {
  2449. long phyConnectTimeMillis = currentTimeMillis - connection.connectTimeMillis;
  2450. if (phyConnectTimeMillis > phyTimeoutMillis) {
  2451. evictConnections[evictCount++] = connection;
  2452. continue;
  2453. }
  2454. }
  2455. long idleMillis = currentTimeMillis - connection.lastActiveTimeMillis;
  2456. if (idleMillis < minEvictableIdleTimeMillis
  2457. && idleMillis < keepAliveBetweenTimeMillis
  2458. ) {
  2459. break;
  2460. }
  2461. if (idleMillis >= minEvictableIdleTimeMillis) {
  2462. if (checkTime && i < checkCount) {
  2463. evictConnections[evictCount++] = connection;
  2464. continue;
  2465. } else if (idleMillis > maxEvictableIdleTimeMillis) {
  2466. evictConnections[evictCount++] = connection;
  2467. continue;
  2468. }
  2469. }
  2470. if (keepAlive && idleMillis >= keepAliveBetweenTimeMillis) {
  2471. keepAliveConnections[keepAliveCount++] = connection;
  2472. }
  2473. } else {
  2474. if (i < checkCount) {
  2475. evictConnections[evictCount++] = connection;
  2476. } else {
  2477. break;
  2478. }
  2479. }
  2480. }
  2481. int removeCount = evictCount + keepAliveCount;
  2482. if (removeCount > 0) {
  2483. System.arraycopy(connections, removeCount, connections, 0, poolingCount - removeCount);
  2484. Arrays.fill(connections, poolingCount - removeCount, poolingCount, null);
  2485. poolingCount -= removeCount;
  2486. }
  2487. keepAliveCheckCount += keepAliveCount;
  2488. } finally {
  2489. lock.unlock();
  2490. }
  2491. if (evictCount > 0) {
  2492. for (int i = 0; i < evictCount; ++i) {
  2493. DruidConnectionHolder item = evictConnections[i];
  2494. Connection connection = item.getConnection();
  2495. JdbcUtils.close(connection);
  2496. destroyCountUpdater.incrementAndGet(this);
  2497. }
  2498. Arrays.fill(evictConnections, null);
  2499. }
  2500. if (keepAliveCount > 0) {
  2501. // keep order
  2502. for (int i = keepAliveCount - 1; i >= 0; --i) {
  2503. DruidConnectionHolder holer = keepAliveConnections[i];
  2504. Connection connection = holer.getConnection();
  2505. holer.incrementKeepAliveCheckCount();
  2506. boolean validate = false;
  2507. try {
  2508. this.validateConnection(connection);
  2509. validate = true;
  2510. } catch (Throwable error) {
  2511. if (LOG.isDebugEnabled()) {
  2512. LOG.debug("keepAliveErr", error);
  2513. }
  2514. // skip
  2515. }
  2516. boolean discard = !validate;
  2517. if (validate) {
  2518. holer.lastKeepTimeMillis = System.currentTimeMillis();
  2519. boolean putOk = put(holer);
  2520. if (!putOk) {
  2521. discard = true;
  2522. }
  2523. }
  2524. if (discard) {
  2525. try {
  2526. connection.close();
  2527. } catch (Exception e) {
  2528. // skip
  2529. }
  2530. lock.lock();
  2531. try {
  2532. discardCount++;
  2533. if (activeCount <= minIdle) {
  2534. emptySignal();
  2535. }
  2536. } finally {
  2537. lock.unlock();
  2538. }
  2539. }
  2540. }
  2541. this.getDataSourceStat().addKeepAliveCheckCount(keepAliveCount);
  2542. Arrays.fill(keepAliveConnections, null);
  2543. }
  2544. }
  2545. public int getWaitThreadCount() {
  2546. lock.lock();
  2547. try {
  2548. return lock.getWaitQueueLength(notEmpty);
  2549. } finally {
  2550. lock.unlock();
  2551. }
  2552. }
  2553. public long getNotEmptyWaitCount() {
  2554. return notEmptyWaitCount;
  2555. }
  2556. public int getNotEmptyWaitThreadCount() {
  2557. lock.lock();
  2558. try {
  2559. return notEmptyWaitThreadCount;
  2560. } finally {
  2561. lock.unlock();
  2562. }
  2563. }
  2564. public int getNotEmptyWaitThreadPeak() {
  2565. lock.lock();
  2566. try {
  2567. return notEmptyWaitThreadPeak;
  2568. } finally {
  2569. lock.unlock();
  2570. }
  2571. }
  2572. public long getNotEmptySignalCount() {
  2573. return notEmptySignalCount;
  2574. }
  2575. public long getNotEmptyWaitMillis() {
  2576. return notEmptyWaitNanos / (1000 * 1000);
  2577. }
  2578. public long getNotEmptyWaitNanos() {
  2579. return notEmptyWaitNanos;
  2580. }
  2581. public int getLockQueueLength() {
  2582. return lock.getQueueLength();
  2583. }
  2584. public int getActivePeak() {
  2585. return activePeak;
  2586. }
  2587. public Date getActivePeakTime() {
  2588. if (activePeakTime <= 0) {
  2589. return null;
  2590. }
  2591. return new Date(activePeakTime);
  2592. }
  2593. public String dump() {
  2594. lock.lock();
  2595. try {
  2596. return this.toString();
  2597. } finally {
  2598. lock.unlock();
  2599. }
  2600. }
  2601. public long getErrorCount() {
  2602. return this.errorCount;
  2603. }
  2604. public String toString() {
  2605. StringBuilder buf = new StringBuilder();
  2606. buf.append("{");
  2607. buf.append("\n\tCreateTime:\"");
  2608. buf.append(Utils.toString(getCreatedTime()));
  2609. buf.append("\"");
  2610. buf.append(",\n\tActiveCount:");
  2611. buf.append(getActiveCount());
  2612. buf.append(",\n\tPoolingCount:");
  2613. buf.append(getPoolingCount());
  2614. buf.append(",\n\tCreateCount:");
  2615. buf.append(getCreateCount());
  2616. buf.append(",\n\tDestroyCount:");
  2617. buf.append(getDestroyCount());
  2618. buf.append(",\n\tCloseCount:");
  2619. buf.append(getCloseCount());
  2620. buf.append(",\n\tConnectCount:");
  2621. buf.append(getConnectCount());
  2622. buf.append(",\n\tConnections:[");
  2623. for (int i = 0; i < poolingCount; ++i) {
  2624. DruidConnectionHolder conn = connections[i];
  2625. if (conn != null) {
  2626. if (i != 0) {
  2627. buf.append(",");
  2628. }
  2629. buf.append("\n\t\t");
  2630. buf.append(conn.toString());
  2631. }
  2632. }
  2633. buf.append("\n\t]");
  2634. buf.append("\n}");
  2635. if (this.isPoolPreparedStatements()) {
  2636. buf.append("\n\n[");
  2637. for (int i = 0; i < poolingCount; ++i) {
  2638. DruidConnectionHolder conn = connections[i];
  2639. if (conn != null) {
  2640. if (i != 0) {
  2641. buf.append(",");
  2642. }
  2643. buf.append("\n\t{\n\tID:");
  2644. buf.append(System.identityHashCode(conn.getConnection()));
  2645. PreparedStatementPool pool = conn.getStatementPool();
  2646. buf.append(", \n\tpoolStatements:[");
  2647. int entryIndex = 0;
  2648. try {
  2649. for (Map.Entry<PreparedStatementKey, PreparedStatementHolder> entry : pool.getMap().entrySet()) {
  2650. if (entryIndex != 0) {
  2651. buf.append(",");
  2652. }
  2653. buf.append("\n\t\t{hitCount:");
  2654. buf.append(entry.getValue().getHitCount());
  2655. buf.append(",sql:\"");
  2656. buf.append(entry.getKey().getSql());
  2657. buf.append("\"");
  2658. buf.append("\t}");
  2659. entryIndex++;
  2660. }
  2661. } catch (ConcurrentModificationException e) {
  2662. // skip ..
  2663. }
  2664. buf.append("\n\t\t]");
  2665. buf.append("\n\t}");
  2666. }
  2667. }
  2668. buf.append("\n]");
  2669. }
  2670. return buf.toString();
  2671. }
  2672. public List<Map<String, Object>> getPoolingConnectionInfo() {
  2673. List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
  2674. lock.lock();
  2675. try {
  2676. for (int i = 0; i < poolingCount; ++i) {
  2677. DruidConnectionHolder connHolder = connections[i];
  2678. Connection conn = connHolder.getConnection();
  2679. Map<String, Object> map = new LinkedHashMap<String, Object>();
  2680. map.put("id", System.identityHashCode(conn));
  2681. map.put("connectionId", connHolder.getConnectionId());
  2682. map.put("useCount", connHolder.getUseCount());
  2683. if (connHolder.lastActiveTimeMillis > 0) {
  2684. map.put("lastActiveTime", new Date(connHolder.lastActiveTimeMillis));
  2685. }
  2686. if (connHolder.lastKeepTimeMillis > 0) {
  2687. map.put("lastKeepTimeMillis", new Date(connHolder.lastKeepTimeMillis));
  2688. }
  2689. map.put("connectTime", new Date(connHolder.getTimeMillis()));
  2690. map.put("holdability", connHolder.getUnderlyingHoldability());
  2691. map.put("transactionIsolation", connHolder.getUnderlyingTransactionIsolation());
  2692. map.put("autoCommit", connHolder.underlyingAutoCommit);
  2693. map.put("readoOnly", connHolder.isUnderlyingReadOnly());
  2694. if (connHolder.isPoolPreparedStatements()) {
  2695. List<Map<String, Object>> stmtCache = new ArrayList<Map<String, Object>>();
  2696. PreparedStatementPool stmtPool = connHolder.getStatementPool();
  2697. for (PreparedStatementHolder stmtHolder : stmtPool.getMap().values()) {
  2698. Map<String, Object> stmtInfo = new LinkedHashMap<String, Object>();
  2699. stmtInfo.put("sql", stmtHolder.key.getSql());
  2700. stmtInfo.put("defaultRowPrefetch", stmtHolder.getDefaultRowPrefetch());
  2701. stmtInfo.put("rowPrefetch", stmtHolder.getRowPrefetch());
  2702. stmtInfo.put("hitCount", stmtHolder.getHitCount());
  2703. stmtCache.add(stmtInfo);
  2704. }
  2705. map.put("pscache", stmtCache);
  2706. }
  2707. map.put("keepAliveCheckCount", connHolder.getKeepAliveCheckCount());
  2708. list.add(map);
  2709. }
  2710. } finally {
  2711. lock.unlock();
  2712. }
  2713. return list;
  2714. }
  2715. public void logTransaction(TransactionInfo info) {
  2716. long transactionMillis = info.getEndTimeMillis() - info.getStartTimeMillis();
  2717. if (transactionThresholdMillis > 0 && transactionMillis > transactionThresholdMillis) {
  2718. StringBuilder buf = new StringBuilder();
  2719. buf.append("long time transaction, take ");
  2720. buf.append(transactionMillis);
  2721. buf.append(" ms : ");
  2722. for (String sql : info.getSqlList()) {
  2723. buf.append(sql);
  2724. buf.append(";");
  2725. }
  2726. LOG.error(buf.toString(), new TransactionTimeoutException());
  2727. }
  2728. }
  2729. @Override
  2730. public String getVersion() {
  2731. return VERSION.getVersionNumber();
  2732. }
  2733. @Override
  2734. public JdbcDataSourceStat getDataSourceStat() {
  2735. return dataSourceStat;
  2736. }
  2737. public Object clone() throws CloneNotSupportedException {
  2738. return cloneDruidDataSource();
  2739. }
  2740. public DruidDataSource cloneDruidDataSource() {
  2741. DruidDataSource x = new DruidDataSource();
  2742. cloneTo(x);
  2743. return x;
  2744. }
  2745. public Map<String, Object> getStatDataForMBean() {
  2746. try {
  2747. Map<String, Object> map = new HashMap<String, Object>();
  2748. // 0 - 4
  2749. map.put("Name", this.getName());
  2750. map.put("URL", this.getUrl());
  2751. map.put("CreateCount", this.getCreateCount());
  2752. map.put("DestroyCount", this.getDestroyCount());
  2753. map.put("ConnectCount", this.getConnectCount());
  2754. // 5 - 9
  2755. map.put("CloseCount", this.getCloseCount());
  2756. map.put("ActiveCount", this.getActiveCount());
  2757. map.put("PoolingCount", this.getPoolingCount());
  2758. map.put("LockQueueLength", this.getLockQueueLength());
  2759. map.put("WaitThreadCount", this.getNotEmptyWaitThreadPeak());
  2760. // 10 - 14
  2761. map.put("InitialSize", this.getInitialSize());
  2762. map.put("MaxActive", this.getMaxActive());
  2763. map.put("MinIdle", this.getMinIdle());
  2764. map.put("PoolPreparedStatements", this.isPoolPreparedStatements());
  2765. map.put("TestOnBorrow", this.isTestOnBorrow());
  2766. // 15 - 19
  2767. map.put("TestOnReturn", this.isTestOnReturn());
  2768. map.put("MinEvictableIdleTimeMillis", this.minEvictableIdleTimeMillis);
  2769. map.put("ConnectErrorCount", this.getConnectErrorCount());
  2770. map.put("CreateTimespanMillis", this.getCreateTimespanMillis());
  2771. map.put("DbType", this.dbType);
  2772. // 20 - 24
  2773. map.put("ValidationQuery", this.getValidationQuery());
  2774. map.put("ValidationQueryTimeout", this.getValidationQueryTimeout());
  2775. map.put("DriverClassName", this.getDriverClassName());
  2776. map.put("Username", this.getUsername());
  2777. map.put("RemoveAbandonedCount", this.getRemoveAbandonedCount());
  2778. // 25 - 29
  2779. map.put("NotEmptyWaitCount", this.getNotEmptyWaitCount());
  2780. map.put("NotEmptyWaitNanos", this.getNotEmptyWaitNanos());
  2781. map.put("ErrorCount", this.getErrorCount());
  2782. map.put("ReusePreparedStatementCount", this.getCachedPreparedStatementHitCount());
  2783. map.put("StartTransactionCount", this.getStartTransactionCount());
  2784. // 30 - 34
  2785. map.put("CommitCount", this.getCommitCount());
  2786. map.put("RollbackCount", this.getRollbackCount());
  2787. map.put("LastError", JMXUtils.getErrorCompositeData(this.getLastError()));
  2788. map.put("LastCreateError", JMXUtils.getErrorCompositeData(this.getLastCreateError()));
  2789. map.put("PreparedStatementCacheDeleteCount", this.getCachedPreparedStatementDeleteCount());
  2790. // 35 - 39
  2791. map.put("PreparedStatementCacheAccessCount", this.getCachedPreparedStatementAccessCount());
  2792. map.put("PreparedStatementCacheMissCount", this.getCachedPreparedStatementMissCount());
  2793. map.put("PreparedStatementCacheHitCount", this.getCachedPreparedStatementHitCount());
  2794. map.put("PreparedStatementCacheCurrentCount", this.getCachedPreparedStatementCount());
  2795. map.put("Version", this.getVersion());
  2796. // 40 -
  2797. map.put("LastErrorTime", this.getLastErrorTime());
  2798. map.put("LastCreateErrorTime", this.getLastCreateErrorTime());
  2799. map.put("CreateErrorCount", this.getCreateErrorCount());
  2800. map.put("DiscardCount", this.getDiscardCount());
  2801. map.put("ExecuteQueryCount", this.getExecuteQueryCount());
  2802. map.put("ExecuteUpdateCount", this.getExecuteUpdateCount());
  2803. return map;
  2804. } catch (JMException ex) {
  2805. throw new IllegalStateException("getStatData error", ex);
  2806. }
  2807. }
  2808. public Map<String, Object> getStatData() {
  2809. final int activeCount;
  2810. final int activePeak;
  2811. final Date activePeakTime;
  2812. final int poolingCount;
  2813. final int poolingPeak;
  2814. final Date poolingPeakTime;
  2815. final long connectCount;
  2816. final long closeCount;
  2817. lock.lock();
  2818. try {
  2819. poolingCount = this.poolingCount;
  2820. poolingPeak = this.poolingPeak;
  2821. poolingPeakTime = this.getPoolingPeakTime();
  2822. activeCount = this.activeCount;
  2823. activePeak = this.activePeak;
  2824. activePeakTime = this.getActivePeakTime();
  2825. connectCount = this.connectCount;
  2826. closeCount = this.closeCount;
  2827. } finally {
  2828. lock.unlock();
  2829. }
  2830. Map<String, Object> dataMap = new LinkedHashMap<String, Object>();
  2831. dataMap.put("Identity", System.identityHashCode(this));
  2832. dataMap.put("Name", this.getName());
  2833. dataMap.put("DbType", this.dbType);
  2834. dataMap.put("DriverClassName", this.getDriverClassName());
  2835. dataMap.put("URL", this.getUrl());
  2836. dataMap.put("UserName", this.getUsername());
  2837. dataMap.put("FilterClassNames", this.getFilterClassNames());
  2838. dataMap.put("WaitThreadCount", this.getWaitThreadCount());
  2839. dataMap.put("NotEmptyWaitCount", this.getNotEmptyWaitCount());
  2840. dataMap.put("NotEmptyWaitMillis", this.getNotEmptyWaitMillis());
  2841. dataMap.put("PoolingCount", poolingCount);
  2842. dataMap.put("PoolingPeak", poolingPeak);
  2843. dataMap.put("PoolingPeakTime", poolingPeakTime);
  2844. dataMap.put("ActiveCount", activeCount);
  2845. dataMap.put("ActivePeak", activePeak);
  2846. dataMap.put("ActivePeakTime", activePeakTime);
  2847. dataMap.put("InitialSize", this.getInitialSize());
  2848. dataMap.put("MinIdle", this.getMinIdle());
  2849. dataMap.put("MaxActive", this.getMaxActive());
  2850. dataMap.put("QueryTimeout", this.getQueryTimeout());
  2851. dataMap.put("TransactionQueryTimeout", this.getTransactionQueryTimeout());
  2852. dataMap.put("LoginTimeout", this.getLoginTimeout());
  2853. dataMap.put("ValidConnectionCheckerClassName", this.getValidConnectionCheckerClassName());
  2854. dataMap.put("ExceptionSorterClassName", this.getExceptionSorterClassName());
  2855. dataMap.put("TestOnBorrow", this.isTestOnBorrow());
  2856. dataMap.put("TestOnReturn", this.isTestOnReturn());
  2857. dataMap.put("TestWhileIdle", this.isTestWhileIdle());
  2858. dataMap.put("DefaultAutoCommit", this.isDefaultAutoCommit());
  2859. dataMap.put("DefaultReadOnly", this.getDefaultReadOnly());
  2860. dataMap.put("DefaultTransactionIsolation", this.getDefaultTransactionIsolation());
  2861. dataMap.put("LogicConnectCount", connectCount);
  2862. dataMap.put("LogicCloseCount", closeCount);
  2863. dataMap.put("LogicConnectErrorCount", this.getConnectErrorCount());
  2864. dataMap.put("PhysicalConnectCount", this.getCreateCount());
  2865. dataMap.put("PhysicalCloseCount", this.getDestroyCount());
  2866. dataMap.put("PhysicalConnectErrorCount", this.getCreateErrorCount());
  2867. dataMap.put("ExecuteCount", this.getExecuteCount());
  2868. dataMap.put("ExecuteUpdateCount", this.getExecuteUpdateCount());
  2869. dataMap.put("ExecuteQueryCount", this.getExecuteQueryCount());
  2870. dataMap.put("ExecuteBatchCount", this.getExecuteBatchCount());
  2871. dataMap.put("ErrorCount", this.getErrorCount());
  2872. dataMap.put("CommitCount", this.getCommitCount());
  2873. dataMap.put("RollbackCount", this.getRollbackCount());
  2874. dataMap.put("PSCacheAccessCount", this.getCachedPreparedStatementAccessCount());
  2875. dataMap.put("PSCacheHitCount", this.getCachedPreparedStatementHitCount());
  2876. dataMap.put("PSCacheMissCount", this.getCachedPreparedStatementMissCount());
  2877. dataMap.put("StartTransactionCount", this.getStartTransactionCount());
  2878. dataMap.put("TransactionHistogram", this.getTransactionHistogramValues());
  2879. dataMap.put("ConnectionHoldTimeHistogram", this.getDataSourceStat().getConnectionHoldHistogram().toArray());
  2880. dataMap.put("RemoveAbandoned", this.isRemoveAbandoned());
  2881. dataMap.put("ClobOpenCount", this.getDataSourceStat().getClobOpenCount());
  2882. dataMap.put("BlobOpenCount", this.getDataSourceStat().getBlobOpenCount());
  2883. dataMap.put("KeepAliveCheckCount", this.getDataSourceStat().getKeepAliveCheckCount());
  2884. dataMap.put("KeepAlive", this.isKeepAlive());
  2885. dataMap.put("FailFast", this.isFailFast());
  2886. dataMap.put("MaxWait", this.getMaxWait());
  2887. dataMap.put("MaxWaitThreadCount", this.getMaxWaitThreadCount());
  2888. dataMap.put("PoolPreparedStatements", this.isPoolPreparedStatements());
  2889. dataMap.put("MaxPoolPreparedStatementPerConnectionSize", this.getMaxPoolPreparedStatementPerConnectionSize());
  2890. dataMap.put("MinEvictableIdleTimeMillis", this.minEvictableIdleTimeMillis);
  2891. dataMap.put("MaxEvictableIdleTimeMillis", this.maxEvictableIdleTimeMillis);
  2892. dataMap.put("LogDifferentThread", isLogDifferentThread());
  2893. dataMap.put("RecycleErrorCount", getRecycleErrorCount());
  2894. dataMap.put("PreparedStatementOpenCount", getPreparedStatementCount());
  2895. dataMap.put("PreparedStatementClosedCount", getClosedPreparedStatementCount());
  2896. dataMap.put("UseUnfairLock", isUseUnfairLock());
  2897. dataMap.put("InitGlobalVariants", isInitGlobalVariants());
  2898. dataMap.put("InitVariants", isInitVariants());
  2899. return dataMap;
  2900. }
  2901. public JdbcSqlStat getSqlStat(int sqlId) {
  2902. return this.getDataSourceStat().getSqlStat(sqlId);
  2903. }
  2904. public JdbcSqlStat getSqlStat(long sqlId) {
  2905. return this.getDataSourceStat().getSqlStat(sqlId);
  2906. }
  2907. public Map<String, JdbcSqlStat> getSqlStatMap() {
  2908. return this.getDataSourceStat().getSqlStatMap();
  2909. }
  2910. public Map<String, Object> getWallStatMap() {
  2911. WallProviderStatValue wallStatValue = getWallStatValue(false);
  2912. if (wallStatValue != null) {
  2913. return wallStatValue.toMap();
  2914. }
  2915. return null;
  2916. }
  2917. public WallProviderStatValue getWallStatValue(boolean reset) {
  2918. for (Filter filter : this.filters) {
  2919. if (filter instanceof WallFilter) {
  2920. WallFilter wallFilter = (WallFilter) filter;
  2921. return wallFilter.getProvider().getStatValue(reset);
  2922. }
  2923. }
  2924. return null;
  2925. }
  2926. public Lock getLock() {
  2927. return lock;
  2928. }
  2929. @Override
  2930. public boolean isWrapperFor(Class<?> iface) {
  2931. for (Filter filter : this.filters) {
  2932. if (filter.isWrapperFor(iface)) {
  2933. return true;
  2934. }
  2935. }
  2936. if (this.statLogger != null
  2937. && (this.statLogger.getClass() == iface || DruidDataSourceStatLogger.class == iface)) {
  2938. return true;
  2939. }
  2940. return super.isWrapperFor(iface);
  2941. }
  2942. @SuppressWarnings("unchecked")
  2943. public <T> T unwrap(Class<T> iface) {
  2944. for (Filter filter : this.filters) {
  2945. if (filter.isWrapperFor(iface)) {
  2946. return (T) filter;
  2947. }
  2948. }
  2949. if (this.statLogger != null
  2950. && (this.statLogger.getClass() == iface || DruidDataSourceStatLogger.class == iface)) {
  2951. return (T) statLogger;
  2952. }
  2953. return super.unwrap(iface);
  2954. }
  2955. public boolean isLogDifferentThread() {
  2956. return logDifferentThread;
  2957. }
  2958. public void setLogDifferentThread(boolean logDifferentThread) {
  2959. this.logDifferentThread = logDifferentThread;
  2960. }
  2961. public DruidPooledConnection tryGetConnection() throws SQLException {
  2962. if (poolingCount == 0) {
  2963. return null;
  2964. }
  2965. return getConnection();
  2966. }
  2967. @Override
  2968. public int fill() throws SQLException {
  2969. return this.fill(this.maxActive);
  2970. }
  2971. @Override
  2972. public int fill(int toCount) throws SQLException {
  2973. if (closed) {
  2974. throw new DataSourceClosedException("dataSource already closed at " + new Date(closeTimeMillis));
  2975. }
  2976. if (toCount < 0) {
  2977. throw new IllegalArgumentException("toCount can't not be less than zero");
  2978. }
  2979. init();
  2980. if (toCount > this.maxActive) {
  2981. toCount = this.maxActive;
  2982. }
  2983. int fillCount = 0;
  2984. for (;;) {
  2985. try {
  2986. lock.lockInterruptibly();
  2987. } catch (InterruptedException e) {
  2988. connectErrorCountUpdater.incrementAndGet(this);
  2989. throw new SQLException("interrupt", e);
  2990. }
  2991. boolean fillable = this.isFillable(toCount);
  2992. lock.unlock();
  2993. if (!fillable) {
  2994. break;
  2995. }
  2996. DruidConnectionHolder holder;
  2997. try {
  2998. PhysicalConnectionInfo pyConnInfo = createPhysicalConnection();
  2999. holder = new DruidConnectionHolder(this, pyConnInfo);
  3000. } catch (SQLException e) {
  3001. LOG.error("fill connection error, url: " + this.jdbcUrl, e);
  3002. connectErrorCountUpdater.incrementAndGet(this);
  3003. throw e;
  3004. }
  3005. try {
  3006. lock.lockInterruptibly();
  3007. } catch (InterruptedException e) {
  3008. connectErrorCountUpdater.incrementAndGet(this);
  3009. throw new SQLException("interrupt", e);
  3010. }
  3011. try {
  3012. if (!this.isFillable(toCount)) {
  3013. JdbcUtils.close(holder.getConnection());
  3014. LOG.info("fill connections skip.");
  3015. break;
  3016. }
  3017. this.putLast(holder, System.currentTimeMillis());
  3018. fillCount++;
  3019. } finally {
  3020. lock.unlock();
  3021. }
  3022. }
  3023. if (LOG.isInfoEnabled()) {
  3024. LOG.info("fill " + fillCount + " connections");
  3025. }
  3026. return fillCount;
  3027. }
  3028. private boolean isFillable(int toCount) {
  3029. int currentCount = this.poolingCount + this.activeCount;
  3030. if (currentCount >= toCount || currentCount >= this.maxActive) {
  3031. return false;
  3032. } else {
  3033. return true;
  3034. }
  3035. }
  3036. public boolean isFull() {
  3037. lock.lock();
  3038. try {
  3039. return this.poolingCount + this.activeCount >= this.maxActive;
  3040. } finally {
  3041. lock.unlock();
  3042. }
  3043. }
  3044. private void emptySignal() {
  3045. if (createScheduler == null) {
  3046. empty.signal();
  3047. return;
  3048. }
  3049. if (createTaskCount >= maxCreateTaskCount) {
  3050. return;
  3051. }
  3052. if (activeCount + poolingCount + createTaskCount >= maxActive) {
  3053. return;
  3054. }
  3055. createTaskCount++;
  3056. CreateConnectionTask task = new CreateConnectionTask();
  3057. this.createSchedulerFuture = createScheduler.submit(task);
  3058. }
  3059. @Override
  3060. public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {
  3061. if (server != null) {
  3062. try {
  3063. if (server.isRegistered(name)) {
  3064. server.unregisterMBean(name);
  3065. }
  3066. } catch (Exception ex) {
  3067. LOG.warn("DruidDataSource preRegister error", ex);
  3068. }
  3069. }
  3070. return name;
  3071. }
  3072. @Override
  3073. public void postRegister(Boolean registrationDone) {
  3074. }
  3075. @Override
  3076. public void preDeregister() throws Exception {
  3077. }
  3078. @Override
  3079. public void postDeregister() {
  3080. }
  3081. public boolean isClosed() {
  3082. return this.closed;
  3083. }
  3084. }

参考阅读

Java魔法类:Unsafe应用解析

面试官:说说 Java 中的 Unsafe 和 CAS

sun.misc.Unsafe.park(Native Method)异常

深入理解sun.misc.Unsafe原理

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/336970
推荐阅读
相关标签
  

闽ICP备14008679号