mybatis 连接池配置

ldspeace 2019-05-18 原文

mybatis 连接池配置

xml形式配置DataSource

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
  <properties resource="/com/cn/cs/config.properties"/>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${oracle.driver}"/>
        <property name="url" value="${oracle.url}"/>
        <property name="username" value="${oracle.username}"/>
        <property name="password" value="${oracle.password}"/>
        <property name="poolMaximumActiveConnections" value="10"/> <!--最大活跃连接数 -->
        <property name="poolMaximumIdleConnections" value="5"/>  <!--最大空闲连接数-->
        <property name="poolTimeToWait" value="20000"/>  <!--创建连接时最大等待时间20s-->
      </dataSource>
    </environment>
  </environments>
  <mappers>
      <mapper resource="/com/cn/cs/mapping/UserCsMapper.xml"/>  
  </mappers>
</configuration>
 

 

 mybatis中DataSource节点有一个 type属性. 有三个可选值: pooled(连接池), unpooled(非连接池), jndi

 mybatis内部定义了一个DataSourceFactory接口

public interface DataSourceFactory {

  void setProperties(Properties props);

  DataSource getDataSource();

}

根据type 属性值分别对应实现类.

    pooled –> PooledDataSourceFactory            

       unpooled –> UnpooledDataSourceFactory  

  jndi–> JndiDataSourceFactory  

这三个实现类都实现了 DataSourceFactory 的 DataSource getDataSource()方法.

   PooledDataSourceFactory.getDataSource() 返回   PooledDataSource.

   UnpooledDataSourceFactory.getDataSource() 返回  UnpooledDataSource

   JndiDataSourceFactory.getDataSource() 返回   环境中的 DataSource

DataSource 将会保存在Environment 的静态内部类Builder中.

连接池的初始化

dataSource 此时只会保存好配置信息.连接池此时并没有创建好连接.只有当程序在调用操作数据库的方法时,才会出示化连接.

管理连接池的类为PooledDateSource  这个类中有一个获取连接的方法.

这个方法会先判断是否有空闲连接,有的话会直接将连接取出来.如果没有则判断当前活跃的连接是否大于最大空闲连接数.如果小于则创建一个新的连接.

否则将旧的连接删掉一个,并创建一个新的连接.

 

 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 connection
          conn = state.idleConnections.remove(0);
          if (log.isDebugEnabled()) {
            log.debug("Checked out connection " + conn.getRealHashCode() + " from pool.");
          }
        } else {
          // Pool does not have available connection
          if (state.activeConnections.size() < poolMaximumActiveConnections) {
            // Can create new connection
            conn = new PooledConnection(dataSource.getConnection(), this);
            if (log.isDebugEnabled()) {
              log.debug("Created connection " + conn.getRealHashCode() + ".");
            }
          } else {
            // Cannot create new connection
            PooledConnection oldestActiveConnection = state.activeConnections.get(0);
            long longestCheckoutTime = oldestActiveConnection.getCheckoutTime();
            if (longestCheckoutTime > poolMaximumCheckoutTime) {
              // Can claim overdue connection
              state.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 following
                     statement like nothing happened.
                     Wrap the bad connection with a new PooledConnection, this will help
                     to not interrupt current executing thread and give current thread a
                     chance to join the next competition for another valid/good database
                     connection. 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 wait
              try {
                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 not
          if (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;
  }

 

posted on 2019-05-18 13:15 兰度speace 阅读() 评论() 编辑 收藏

 

 
版权声明:本文为ldspeace原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/ldspeace/p/10854422.html

mybatis 连接池配置的更多相关文章

  1. MyBatis架构分析

      我们都知道Mybatis是一个非常小巧灵活的ORM框架,深受国内广大开发者的喜爱,我们知道它的出现某种程度 […]...

  2. SpringBoot Maven多模块整合MyBatis 打包jar

    最近公司开始新的项目,框架选定为SpringBoot+Mybatis,本篇主要记录了在IDEA中搭建Sprin […]...

  3. 9、SpringBoot+Mybatis整合——动态sql

    开发工具:STS 前言: mybatis框架中最具特色的便是sql语句中的自定义,而动态sql的使用又使整个框 […]...

  4. mybatis – 通用mapper

    title: 玩转spring-boot-mybatis date: 2019-03-11 19:36:57 […]...

  5. MyBatis框架原理3:缓存

    上一篇[MyBatis框架原理2:SqlSession运行过程][1]介绍了MyBatis的工作流程,其中涉及 […]...

  6. [springboot 开发单体web shop] 2. Mybatis Generator 生成common mapper

    Mybatis Generator tool 在我们开启一个新项目的研发后,通常要编写很多的entity/po […]...

  7. mybatis 逆向工程使用姿势不对,把表清空了,心里慌的一比,于是写了个插件。

    使用mybatis逆向工程的时候,delete方法的使用姿势不对,导致表被清空了,在生产上一刷新后发现表里没数 […]...

  8. 1、SpringBoot+MybatisPlus整合

    1 <?xml version="1.0" encoding="UTF-8"?> 2 <pr […]...

随机推荐

  1. 人工智能系列教程[目录]

    这里是人工智能系列教程的目录~ 写在前面,为啥要出这个系列的教程呢? 总的说来,我们现在有了很多非常厉害的深度 […]...

  2. iconfont svg图标不能更改颜色的解决方法

    问题原因:该部分svg图标可能带有fill属性,这种图标不能本地修改fill属性,需要在项目中移除默认颜色(批 […]...

  3. 关于图片的尺寸处理

      在制作网页的时候,常常会遇到一种情况,我们需要把一些未知尺寸的图片放在一个固定宽高的容器中,这时候我们需要 […]...

  4. Ant Design Pro的dva-loading

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 19 […]...

  5. spring boot2.0一看就会的超详细快速入门(六)-集成Thymeleaf模板引擎

    1.理解Thymeleaf 1.1 Thymeleaf是一个适用于Web和独立环境的服务器端java模板引擎, […]...

  6. 有趣的椭圆曲线加密

    一、概述 椭圆曲线加密算法依赖于椭圆曲线理论,后者理论涵盖的知识比较深广,而且涉及数论中比较深奥的问题。经过数 […]...

  7. requests+正则爬取猫眼电影并将数据存储到mysql数据库

    前面讲了如何通过pymysql操作数据库,这次写一个爬虫来提取信息,并将数据存储到mysql数据库 1.爬取目 […]...

  8. 大前端学习02:Nodejs介绍、安装、入门

    大前端学习02:Nodejs介绍、安装、入门Nodejs介绍与安装:官网:http://nodejs.cn下载,无脑安装;检查是否安装成功:cmd--->node -v (会输出版本号)cmd--->npm -v (会输出版本号) 浏览器...

展开目录

目录导航