mybatis中数据库连接池源代码

默认参数配置

protected int poolMaximumActiveConnections = 10;
  protected int poolMaximumIdleConnections = 5;
  protected int poolMaximumCheckoutTime = 20000;
  protected int poolTimeToWait = 20000;
  protected int poolMaximumLocalBadConnectionTolerance = 3;

默认最大连接数10,最小连接数5

连接池核心代码:

public void forceCloseAll() {
    synchronized (state) {
      expectedConnectionTypeCode = assembleConnectionTypeCode(dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());
      for (int i = state.activeConnections.size(); i > 0; i--) {
        try {
          PooledConnection conn = state.activeConnections.remove(i - 1);
          conn.invalidate();

Connection realConn = conn.getRealConnection();
          if (!realConn.getAutoCommit()) {
            realConn.rollback();
          }
          realConn.close();
        } catch (Exception e) {
          // ignore
        }
      }
      for (int i = state.idleConnections.size(); i > 0; i--) {
        try {
          PooledConnection conn = state.idleConnections.remove(i - 1);
          conn.invalidate();

Connection realConn = conn.getRealConnection();
          if (!realConn.getAutoCommit()) {
            realConn.rollback();
          }
          realConn.close();
        } catch (Exception e) {
          // ignore
        }
      }
    }
    if (log.isDebugEnabled()) {
      log.debug("PooledDataSource forcefully closed/removed all connections.");
    }
  }

/***    Copyright 2009-2020 the original author or authors.**    Licensed under the Apache License, Version 2.0 (the "License");*    you may not use this file except in compliance with the License.*    You may obtain a copy of the License at**       http://www.apache.org/licenses/LICENSE-2.0**    Unless required by applicable law or agreed to in writing, software*    distributed under the License is distributed on an "AS IS" BASIS,*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*    See the License for the specific language governing permissions and*    limitations under the License.*/
package org.apache.ibatis.datasource.pooled;import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.util.logging.Logger;import javax.sql.DataSource;import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;/*** This is a simple, synchronous, thread-safe database connection pool.** @author Clinton Begin*/
public class PooledDataSource implements DataSource {private static final Log log = LogFactory.getLog(PooledDataSource.class);private final PoolState state = new PoolState(this);private final UnpooledDataSource dataSource;// OPTIONAL CONFIGURATION FIELDSprotected int poolMaximumActiveConnections = 10;protected int poolMaximumIdleConnections = 5;protected int poolMaximumCheckoutTime = 20000;protected int poolTimeToWait = 20000;protected int poolMaximumLocalBadConnectionTolerance = 3;protected String poolPingQuery = "NO PING QUERY SET";protected boolean poolPingEnabled;protected int poolPingConnectionsNotUsedFor;private int expectedConnectionTypeCode;public PooledDataSource() {dataSource = new UnpooledDataSource();}public PooledDataSource(UnpooledDataSource dataSource) {this.dataSource = dataSource;}public PooledDataSource(String driver, String url, String username, String password) {dataSource = new UnpooledDataSource(driver, url, username, password);expectedConnectionTypeCode = assembleConnectionTypeCode(dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());}public PooledDataSource(String driver, String url, Properties driverProperties) {dataSource = new UnpooledDataSource(driver, url, driverProperties);expectedConnectionTypeCode = assembleConnectionTypeCode(dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());}public PooledDataSource(ClassLoader driverClassLoader, String driver, String url, String username, String password) {dataSource = new UnpooledDataSource(driverClassLoader, driver, url, username, password);expectedConnectionTypeCode = assembleConnectionTypeCode(dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());}public PooledDataSource(ClassLoader driverClassLoader, String driver, String url, Properties driverProperties) {dataSource = new UnpooledDataSource(driverClassLoader, driver, url, driverProperties);expectedConnectionTypeCode = assembleConnectionTypeCode(dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());}@Overridepublic Connection getConnection() throws SQLException {return popConnection(dataSource.getUsername(), dataSource.getPassword()).getProxyConnection();}@Overridepublic Connection getConnection(String username, String password) throws SQLException {return popConnection(username, password).getProxyConnection();}@Overridepublic void setLoginTimeout(int loginTimeout) {DriverManager.setLoginTimeout(loginTimeout);}@Overridepublic int getLoginTimeout() {return DriverManager.getLoginTimeout();}@Overridepublic void setLogWriter(PrintWriter logWriter) {DriverManager.setLogWriter(logWriter);}@Overridepublic PrintWriter getLogWriter() {return DriverManager.getLogWriter();}public void setDriver(String driver) {dataSource.setDriver(driver);forceCloseAll();}public void setUrl(String url) {dataSource.setUrl(url);forceCloseAll();}public void setUsername(String username) {dataSource.setUsername(username);forceCloseAll();}public void setPassword(String password) {dataSource.setPassword(password);forceCloseAll();}public void setDefaultAutoCommit(boolean defaultAutoCommit) {dataSource.setAutoCommit(defaultAutoCommit);forceCloseAll();}public void setDefaultTransactionIsolationLevel(Integer defaultTransactionIsolationLevel) {dataSource.setDefaultTransactionIsolationLevel(defaultTransactionIsolationLevel);forceCloseAll();}public void setDriverProperties(Properties driverProps) {dataSource.setDriverProperties(driverProps);forceCloseAll();}/*** Sets the default network timeout value to wait for the database operation to complete. See {@link Connection#setNetworkTimeout(java.util.concurrent.Executor, int)}** @param milliseconds*          The time in milliseconds to wait for the database operation to complete.* @since 3.5.2*/public void setDefaultNetworkTimeout(Integer milliseconds) {dataSource.setDefaultNetworkTimeout(milliseconds);forceCloseAll();}/*** The maximum number of active connections.** @param poolMaximumActiveConnections*          The maximum number of active connections*/public void setPoolMaximumActiveConnections(int poolMaximumActiveConnections) {this.poolMaximumActiveConnections = poolMaximumActiveConnections;forceCloseAll();}/*** The maximum number of idle connections.** @param poolMaximumIdleConnections*          The maximum number of idle connections*/public void setPoolMaximumIdleConnections(int poolMaximumIdleConnections) {this.poolMaximumIdleConnections = poolMaximumIdleConnections;forceCloseAll();}/*** The maximum number of tolerance for bad connection happens in one thread* which are applying for new {@link PooledConnection}.** @param poolMaximumLocalBadConnectionTolerance*          max tolerance for bad connection happens in one thread** @since 3.4.5*/public void setPoolMaximumLocalBadConnectionTolerance(int poolMaximumLocalBadConnectionTolerance) {this.poolMaximumLocalBadConnectionTolerance = poolMaximumLocalBadConnectionTolerance;}/*** The maximum time a connection can be used before it *may* be* given away again.** @param poolMaximumCheckoutTime*          The maximum time*/public void setPoolMaximumCheckoutTime(int poolMaximumCheckoutTime) {this.poolMaximumCheckoutTime = poolMaximumCheckoutTime;forceCloseAll();}/*** The time to wait before retrying to get a connection.** @param poolTimeToWait*          The time to wait*/public void setPoolTimeToWait(int poolTimeToWait) {this.poolTimeToWait = poolTimeToWait;forceCloseAll();}/*** The query to be used to check a connection.** @param poolPingQuery*          The query*/public void setPoolPingQuery(String poolPingQuery) {this.poolPingQuery = poolPingQuery;forceCloseAll();}/*** Determines if the ping query should be used.** @param poolPingEnabled*          True if we need to check a connection before using it*/public void setPoolPingEnabled(boolean poolPingEnabled) {this.poolPingEnabled = poolPingEnabled;forceCloseAll();}/*** If a connection has not been used in this many milliseconds, ping the* database to make sure the connection is still good.** @param milliseconds*          the number of milliseconds of inactivity that will trigger a ping*/public void setPoolPingConnectionsNotUsedFor(int milliseconds) {this.poolPingConnectionsNotUsedFor = milliseconds;forceCloseAll();}public String getDriver() {return dataSource.getDriver();}public String getUrl() {return dataSource.getUrl();}public String getUsername() {return dataSource.getUsername();}public String getPassword() {return dataSource.getPassword();}public boolean isAutoCommit() {return dataSource.isAutoCommit();}public Integer getDefaultTransactionIsolationLevel() {return dataSource.getDefaultTransactionIsolationLevel();}public Properties getDriverProperties() {return dataSource.getDriverProperties();}/*** Gets the default network timeout.** @return the default network timeout* @since 3.5.2*/public Integer getDefaultNetworkTimeout() {return dataSource.getDefaultNetworkTimeout();}public int getPoolMaximumActiveConnections() {return poolMaximumActiveConnections;}public int getPoolMaximumIdleConnections() {return poolMaximumIdleConnections;}public int getPoolMaximumLocalBadConnectionTolerance() {return poolMaximumLocalBadConnectionTolerance;}public int getPoolMaximumCheckoutTime() {return poolMaximumCheckoutTime;}public int getPoolTimeToWait() {return poolTimeToWait;}public String getPoolPingQuery() {return poolPingQuery;}public boolean isPoolPingEnabled() {return poolPingEnabled;}public int getPoolPingConnectionsNotUsedFor() {return poolPingConnectionsNotUsedFor;}/*** Closes all active and idle connections in the pool.*/public void forceCloseAll() {synchronized (state) {expectedConnectionTypeCode = assembleConnectionTypeCode(dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());for (int i = state.activeConnections.size(); i > 0; i--) {try {PooledConnection conn = state.activeConnections.remove(i - 1);conn.invalidate();Connection realConn = conn.getRealConnection();if (!realConn.getAutoCommit()) {realConn.rollback();}realConn.close();} catch (Exception e) {// ignore}}for (int i = state.idleConnections.size(); i > 0; i--) {try {PooledConnection conn = state.idleConnections.remove(i - 1);conn.invalidate();Connection realConn = conn.getRealConnection();if (!realConn.getAutoCommit()) {realConn.rollback();}realConn.close();} catch (Exception e) {// ignore}}}if (log.isDebugEnabled()) {log.debug("PooledDataSource forcefully closed/removed all connections.");}}public PoolState getPoolState() {return state;}private int assembleConnectionTypeCode(String url, String username, String password) {return ("" + url + username + password).hashCode();}protected void pushConnection(PooledConnection conn) throws SQLException {synchronized (state) {state.activeConnections.remove(conn);if (conn.isValid()) {if (state.idleConnections.size() < poolMaximumIdleConnections && conn.getConnectionTypeCode() == expectedConnectionTypeCode) {state.accumulatedCheckoutTime += conn.getCheckoutTime();if (!conn.getRealConnection().getAutoCommit()) {conn.getRealConnection().rollback();}PooledConnection newConn = new PooledConnection(conn.getRealConnection(), this);state.idleConnections.add(newConn);newConn.setCreatedTimestamp(conn.getCreatedTimestamp());newConn.setLastUsedTimestamp(conn.getLastUsedTimestamp());conn.invalidate();if (log.isDebugEnabled()) {log.debug("Returned connection " + newConn.getRealHashCode() + " to pool.");}state.notifyAll();} else {state.accumulatedCheckoutTime += conn.getCheckoutTime();if (!conn.getRealConnection().getAutoCommit()) {conn.getRealConnection().rollback();}conn.getRealConnection().close();if (log.isDebugEnabled()) {log.debug("Closed connection " + conn.getRealHashCode() + ".");}conn.invalidate();}} else {if (log.isDebugEnabled()) {log.debug("A bad connection (" + conn.getRealHashCode() + ") attempted to return to the pool, discarding connection.");}state.badConnectionCount++;}}}private PooledConnection popConnection(String username, String password) throws SQLException {boolean countedWait = false;PooledConnection conn = null;long t = System.currentTimeMillis();int localBadConnectionCount = 0;while (conn == null) {synchronized (state) {if (!state.idleConnections.isEmpty()) {// Pool has available connectionconn = state.idleConnections.remove(0);if (log.isDebugEnabled()) {log.debug("Checked out connection " + conn.getRealHashCode() + " from pool.");}} else {// Pool does not have available connectionif (state.activeConnections.size() < poolMaximumActiveConnections) {// Can create new connectionconn = new PooledConnection(dataSource.getConnection(), this);if (log.isDebugEnabled()) {log.debug("Created connection " + conn.getRealHashCode() + ".");}} else {// Cannot create new connectionPooledConnection oldestActiveConnection = state.activeConnections.get(0);long longestCheckoutTime = oldestActiveConnection.getCheckoutTime();if (longestCheckoutTime > poolMaximumCheckoutTime) {// Can claim overdue connectionstate.claimedOverdueConnectionCount++;state.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime;state.accumulatedCheckoutTime += longestCheckoutTime;state.activeConnections.remove(oldestActiveConnection);if (!oldestActiveConnection.getRealConnection().getAutoCommit()) {try {oldestActiveConnection.getRealConnection().rollback();} catch (SQLException e) {/*Just log a message for debug and continue to execute the followingstatement like nothing happened.Wrap the bad connection with a new PooledConnection, this will helpto not interrupt current executing thread and give current thread achance to join the next competition for another valid/good databaseconnection. At the end of this loop, bad {@link @conn} will be set as null.*/log.debug("Bad connection. Could not roll back");}}conn = new PooledConnection(oldestActiveConnection.getRealConnection(), this);conn.setCreatedTimestamp(oldestActiveConnection.getCreatedTimestamp());conn.setLastUsedTimestamp(oldestActiveConnection.getLastUsedTimestamp());oldestActiveConnection.invalidate();if (log.isDebugEnabled()) {log.debug("Claimed overdue connection " + conn.getRealHashCode() + ".");}} else {// Must waittry {if (!countedWait) {state.hadToWaitCount++;countedWait = true;}if (log.isDebugEnabled()) {log.debug("Waiting as long as " + poolTimeToWait + " milliseconds for connection.");}long wt = System.currentTimeMillis();state.wait(poolTimeToWait);state.accumulatedWaitTime += System.currentTimeMillis() - wt;} catch (InterruptedException e) {break;}}}}if (conn != null) {// ping to server and check the connection is valid or notif (conn.isValid()) {if (!conn.getRealConnection().getAutoCommit()) {conn.getRealConnection().rollback();}conn.setConnectionTypeCode(assembleConnectionTypeCode(dataSource.getUrl(), username, password));conn.setCheckoutTimestamp(System.currentTimeMillis());conn.setLastUsedTimestamp(System.currentTimeMillis());state.activeConnections.add(conn);state.requestCount++;state.accumulatedRequestTime += System.currentTimeMillis() - t;} else {if (log.isDebugEnabled()) {log.debug("A bad connection (" + conn.getRealHashCode() + ") was returned from the pool, getting another connection.");}state.badConnectionCount++;localBadConnectionCount++;conn = null;if (localBadConnectionCount > (poolMaximumIdleConnections + poolMaximumLocalBadConnectionTolerance)) {if (log.isDebugEnabled()) {log.debug("PooledDataSource: Could not get a good connection to the database.");}throw new SQLException("PooledDataSource: Could not get a good connection to the database.");}}}}}if (conn == null) {if (log.isDebugEnabled()) {log.debug("PooledDataSource: Unknown severe error condition.  The connection pool returned a null connection.");}throw new SQLException("PooledDataSource: Unknown severe error condition.  The connection pool returned a null connection.");}return conn;}/*** Method to check to see if a connection is still usable** @param conn*          - the connection to check* @return True if the connection is still usable*/protected boolean pingConnection(PooledConnection conn) {boolean result = true;try {result = !conn.getRealConnection().isClosed();} catch (SQLException e) {if (log.isDebugEnabled()) {log.debug("Connection " + conn.getRealHashCode() + " is BAD: " + e.getMessage());}result = false;}if (result && poolPingEnabled && poolPingConnectionsNotUsedFor >= 0&& conn.getTimeElapsedSinceLastUse() > poolPingConnectionsNotUsedFor) {try {if (log.isDebugEnabled()) {log.debug("Testing connection " + conn.getRealHashCode() + " ...");}Connection realConn = conn.getRealConnection();try (Statement statement = realConn.createStatement()) {statement.executeQuery(poolPingQuery).close();}if (!realConn.getAutoCommit()) {realConn.rollback();}result = true;if (log.isDebugEnabled()) {log.debug("Connection " + conn.getRealHashCode() + " is GOOD!");}} catch (Exception e) {log.warn("Execution of ping query '" + poolPingQuery + "' failed: " + e.getMessage());try {conn.getRealConnection().close();} catch (Exception e2) {// ignore}result = false;if (log.isDebugEnabled()) {log.debug("Connection " + conn.getRealHashCode() + " is BAD: " + e.getMessage());}}}return result;}/*** Unwraps a pooled connection to get to the 'real' connection** @param conn*          - the pooled connection to unwrap* @return The 'real' connection*/public static Connection unwrapConnection(Connection conn) {if (Proxy.isProxyClass(conn.getClass())) {InvocationHandler handler = Proxy.getInvocationHandler(conn);if (handler instanceof PooledConnection) {return ((PooledConnection) handler).getRealConnection();}}return conn;}@Overrideprotected void finalize() throws Throwable {forceCloseAll();super.finalize();}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {throw new SQLException(getClass().getName() + " is not a wrapper.");}@Overridepublic boolean isWrapperFor(Class<?> iface) {return false;}@Overridepublic Logger getParentLogger() {return Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);}}

Mybatis核心源码赏析(五)相关推荐

  1. Mybatis核心源码赏析(一)

    Mybatis的是SpringMVC+Mybatis和数据库连接和操作的核心组件. 下面赏析一下Mybatis的核心源码包 减少我们写XML配置的mapper源代码 /** Copyright (c) ...

  2. Mybatis核心源码赏析(二)

    我们这次只看(一)里面的的这个类. BaseMapper<T> BaseMapper<T> 继承了 Mapper<T> Mapper<T>的源码为 为什 ...

  3. MyBatis核心源码剖析(SqlSession XML解析 Mapper executor SQL执行过程 自定义类型处理器 缓存 日志)

    MyBatis核心源码剖析 MyBatis核心源码剖析 1 MyBatis源码概述 1.1 为什么要看MyBatis框架的源码 1.2 如何深入学习MyBatis源码 1.3 源码分析的5大原则 2 ...

  4. Mybatis 核心源码分析

    一.Mybatis 整体执行流程 二.Mybatis 具体流程源码分析 三.源码分析 写一个测试类,来具体分析Mybatis 的执行流程: public class MybatisTest {publ ...

  5. Android版数据结构与算法(五):LinkedHashMap核心源码彻底分析

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 上一篇基于哈希表实现HashMap核心源码彻底分析 分析了HashMap的源码,主要分析了扩容机制,如果感兴趣的可以去看看,扩容机制那几行最难懂的 ...

  6. halcon区域腐蚀膨胀算子_超越halcon速度的二值图像的腐蚀和膨胀,实现目前最快的半径相关类算法(附核心源码)。...

    超越halcon速度的二值图像的腐蚀和膨胀,实现目前最快的半径相关类算法(附核心源码). 发布时间:2019-03-20 12:32, 浏览次数:1259 , 标签: halcon 我在两年前的博客里 ...

  7. Dubbo核心源码之SPI扩展

    本文来说下Dubbo核心源码之SPI扩展 文章目录 概述 Java中SPI机制详解 Dubbo SPI扩展 扩展功能介绍 扩展源码分析 ExtensionLoader初始化 配置文件扫描 扩展适配器 ...

  8. RocketMQ源码系列(一) NameServer 核心源码解析

    目录 一.NameServer 介绍 二.NameServer 功能列表 三.NameServer 架构分析 四.NameServer 工程目录解析 五.NameServer 启动流程分析 1)  创 ...

  9. 新书上市 | Vue 3.0 核心源码解析,这本书给Vue学习提供新方法

    Vue.js 作为一款极简的 MVVM 框架,因其轻量.易上手,得到了众多开发者的喜爱. 自从 2014 年 Vue 诞生以来,这个框架设计的初衷,尤大说只是为了设计一个让自己用起来舒服的框架,随着受 ...

最新文章

  1. 【4】青龙面板系列教程之QQ通知机器人XDD-plus安装
  2. 各样本观察值均加同一常数_对色师傅分享:如何使不同观察者在灯箱下观察的色光一致?...
  3. 块级元素和行内元素的区别
  4. 教你精确计算 I2C 上拉电阻阻值
  5. 3.7 ExtJS RadioGroup(单选按钮组) 使用及注意事项
  6. 有道口语大师APP评测:语音识别准确度低
  7. C# C++ 共享内存 结构体读写 结构体中嵌套结构体 结构体中带string Char*的处理方式
  8. SPOJ VLATTICE Visible Lattice Points 莫比乌斯反演
  9. DoIP诊断技术一点通
  10. 001.UG_NX概述
  11. 十大战略工具(10)—— 商业模式画布
  12. SHIO世硕科技马新云携全体员工:2021,在此感谢所有的一切!
  13. 有了域名,怎么搭建自己的网站?
  14. linux的的shell记忆
  15. 网站域名服务器加密,网站域名利用https防劫持方法
  16. EasyPusher安卓Android手机直播推送之MediaCodec 硬编码H264格式
  17. 风控每日一问:互联网金融产品如何利用大数据做风控?
  18. 视频86免费影院-视频电影网聚平台
  19. html插缝小游戏,HTML5游戏 - 见缝插针
  20. Java中long类型直接赋值大数字的问题

热门文章

  1. Java并发编程书籍推荐,丹丹学妹哭着对我说:学长(1)
  2. 2022年初级审计师考试精选试题及答案
  3. C# partial 作用
  4. 美工死不瞑目系列之SVG推锅技巧!
  5. xUtils使用详解(一)
  6. vue组件引入外部js同时获取变量,解决重复引入
  7. android使用gridview的书架效果
  8. 京津冀交通一体化步入全面建设 北三县、平谷区接入首都地铁网
  9. 网络工程师必须搞清楚MPLS与专线的区别
  10. python评论数据分析_Python亚马逊智能产品评论数据分析