Tomcat 中的 JDBC Pool

什么是链接池

什么是 Connection Pool -- 链接池呢?html

我就不解释了。不太清楚的看这篇文章 [生产级别Nodejs开发实践-使用链接池](这篇文章的前半部分讲述了什么是链接池)java

Tomcat中的jdbc链接池

它的英文文档在:[The Tomcat JDBC Connection Pool]mysql

Tomcat 不只是很是受欢迎的 Servlet 容器,也是同时为咱们提供了不少很是实用组件。 jdbc pool 就是其中一个很是实用且高效的 jdbc 链接池的实现. Tomcat 官方大概列出了15条tomcat相对于其余链接池的优势,我这里就不在详细解释了。sql

jdbc pool 组件存在于 tomcat8 release 版本的 lib/tomcat-jdbc.jar 包中。数据库

图片描述

咱们所使用的到全部类都存在于 org.apache.tomcat.jdbc.pool 包名下。apache

依赖

这里面咱们以 mysql 做为数据库来演示
添加 mysql-connector 依赖segmentfault

xml<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.34</version>
</dependency>

固然也少不了咱们的 tomcat-jdbctomcat

xml<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-jdbc</artifactId>
    <version>8.0.15</version>
</dependency>

要注意的是 tomcat-jdbc 依赖 tomcat-juli 包,这个包是在tomcat中的日志框架。几乎被全部tomcat包所依赖。若是使用maven安装依赖的话,就不用理会,由于是会被自动安装的,若是单独下载jar包的话,仍是要下载这个jar包到CLASS_PATHapp

用代码来描述

废话到这儿,该上点代码了。
怎么建立一个 jdbc 链接池池实例呢?框架

javaimport java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;

// main
// 建立链接池属性对象
PoolProperties poolProps = new PoolProperties();
poolProps.setUrl("jdbc:mysql://localhost:3306/test");

poolProps.setDriverClassName("com.mysql.jdbc.Driver");

poolProps.setUsername("root");

poolProps.setPassword("123456");

// 建立链接池, 使用了 tomcat 提供的的实现,它实现了 javax.sql.DataSource 接口
DataSource dataSource = new DataSource();
// 为链接池设置属性
dataSource.setPoolProperties(poolProps);

try (Connection conn = dataSource.getConnection()) {

    PreparedStatement state = conn.prepareStatement("select * from book");

    ResultSet result = state.executeQuery();

    StringBuilder stringBuilder = new StringBuilder();

    while ( result.next() ) {
            stringBuilder.append("[ id: "+ result.getInt("id") + ", ").append("name: " + result.getString("name") + ",\t").append("publisher: " + result.getString("publisher")).append(" ]\n");
    }

    System.out.println(stringBuilder.toString());

} 
catch (SQLException e) 
{
    e.printStackTrace();
}

经过代码能够看出,链接池的建立很简单。PoolProperties 类是管理着链接池属性。咱们配置链接池,都是经过这个类。

来看看这个类的属性,如下有 50 个属性,来控制着链接池和池中的链接的工做状态和生命周期。接下来我会对经常使用的属性进行解释。

javaprivate volatile Properties dbProperties = new Properties();
    private volatile String url = null;
    private volatile String driverClassName = null;
    private volatile Boolean defaultAutoCommit = null;
    private volatile Boolean defaultReadOnly = null;
    private volatile int defaultTransactionIsolation = DataSourceFactory.UNKNOWN_TRANSACTIONISOLATION;
    private volatile String defaultCatalog = null;
    private volatile String connectionProperties;
    private volatile int initialSize = 10;
    private volatile int maxActive = DEFAULT_MAX_ACTIVE;
    private volatile int maxIdle = maxActive;
    private volatile int minIdle = initialSize;
    private volatile int maxWait = 30000;
    private volatile String validationQuery;
    private volatile int validationQueryTimeout = -1;
    private volatile String validatorClassName;
    private volatile Validator validator;
    private volatile boolean testOnBorrow = false;
    private volatile boolean testOnReturn = false;
    private volatile boolean testWhileIdle = false;
    private volatile int timeBetweenEvictionRunsMillis = 5000;
    private volatile int numTestsPerEvictionRun;
    private volatile int minEvictableIdleTimeMillis = 60000;
    private volatile boolean accessToUnderlyingConnectionAllowed = true;
    private volatile boolean removeAbandoned = false;
    private volatile int removeAbandonedTimeout = 60;
    private volatile boolean logAbandoned = false;
    private volatile String name = "Tomcat Connection Pool["+(poolCounter.addAndGet(1))+"-"+System.identityHashCode(PoolProperties.class)+"]";
    private volatile String password;
    private volatile String username;
    private volatile long validationInterval = 30000;
    private volatile boolean jmxEnabled = true;
    private volatile String initSQL;
    private volatile boolean testOnConnect =false;
    private volatile String jdbcInterceptors=null;
    private volatile boolean fairQueue = true;
    private volatile boolean useEquals = true;
    private volatile int abandonWhenPercentageFull = 0;
    private volatile long maxAge = 0;
    private volatile boolean useLock = false;
    private volatile InterceptorDefinition[] interceptors = null;
    private volatile int suspectTimeout = 0;
    private volatile Object dataSource = null;
    private volatile String dataSourceJNDI = null;
    private volatile boolean alternateUsernameAllowed = false;
    private volatile boolean commitOnReturn = false;
    private volatile boolean rollbackOnReturn = false;
    private volatile boolean useDisposableConnectionFacade = true;
    private volatile boolean logValidationErrors = false;
    private volatile boolean propagateInterruptState = false;
    private volatile boolean ignoreExceptionOnPreLoad = false;

url, driverClassName, username, password 这些属性知道jdbc的同窗,我就不解释了。

  • name
    链接池的名称

  • defaultAutoCommit
    指定由链接池所建立的链接的自动提交(auto-commit)状态。

  • DefaultReadOnly
    由链接池所建立的链接对数据库的只读属性

  • DefaultTransactionIsolation
    指定由链接池所建立的链接的事务级别(TransactionIsolation)。可用值为下列之一:(详情可见javadoc)
    NONE, READ_COMMITTED, READ_UNCOMMITTED, REPEATABLE_READ, SERIALIZABLE

  • MinEvictableIdleTimeMillis

  • JmxEnabled
    开启jmx的管理功能

  • TestWhileIdle
    会使用测试线程,测试池中链接是否可以正常使用。

  • ValidationQuery
    指定链接进入空闲状态时是否通过空闲对象驱逐进程的校验(若是存在空闲对象驱逐进程)。若是校验未经过,则该链接被链接池断掉。
    注意:要想值为true时该设置生效,则validationQuery参数必须为一个非空字串。

  • TestOnBorrow
    指定链接被调用时是否通过校验。若是校验未经过,则该链接被链接池断掉,并由链接池尝试调用另外一个链接。
    指定链接返回到池中时是否通过校验。
    注意:要想值为true时该设置生效,则validationQuery参数必须为一个非空字串。

  • TestOnReturn
    指定链接返回到池中时是否通过校验。
    注意:要想值为true时该设置生效,则validationQuery参数必须为一个非空字串。

  • ValidationInterval
    以毫秒为单位验证时间间隔。

  • TimeBetweenEvictionRunsMillis
    以毫秒表示的空闲对象驱逐进程由运行状态进入休眠状态的数值。值为非正数时表示不运行任何空闲对象驱逐进程。

  • MaxActive
    池中 工做链接的最大个数,此值为非正数是表述不限制

  • InitialSize
    以毫秒表示的当链接池中没有可用链接时等待可用链接返回的时间,超时则抛出异常,值为-1时无限期等待。

  • MaxWait
    以毫秒表示的当链接池中没有可用链接时等待可用链接返回的时间,超时则抛出异常,值为-1时无限期等待。

  • MinIdle
    池中最小空闲链接数,当链接数少于此值时,池会建立链接来补充到该值的数量

  • MaxIdle
    池中容许的最大链接数,值为非正数时表示不限制

  • NumTestsPerEvictionRun
    链接池检查每一个空闲对象驱逐进程的对象数量(若是存在空闲对象驱逐进程)

  • MinEvictableIdleTimeMillis
    以毫秒表示的链接被空闲对象驱逐进程驱逐前在池中保持空闲状态的最小时间(若是存在空闲对象驱逐进程)。

  • LogAbandoned
    当清除无效链接时是否在日志中记录清除信息的标志。 记录无效的语句和链接,并附加每一个链接开启或新建一个语句的系统开销。若是你启用了“removeAbandoned”,可能会致使被设为无效的链接被链接池回收。
    这个机制将会在知足下列两个条件时启动:(getNumIdle() < 2) 和 (getNumActive() > getMaxActive() - 3)
    例如:假设maxActive=20,而当前已经拥有18个活动链接,1个空闲链接,“removeAbandoned”机制将会启动。 可是只有在活动链接没有使用的时长超过“removeAbandonedTimeout”(默认为300秒)的链接被清除。在遍历结果集时,所使用的链接不会被标为活动链接。

  • RemoveAbandoned
    是否清除已经超过“removeAbandonedTimout”设置的无效链接。
    若是值为“true”则超过“removeAbandonedTimout”设置的无效链接将会被清除。设置此属性能够从那些没有合适关闭链接的程序中恢复数据库的链接。
    记录无效的语句和链接,并附加每一个链接开启或新建一个语句的系统开销。

  • RemoveAbandonedTimeout
    以秒表示的清除无效链接的时限。

  • JdbcInterceptors
    设置 tomcat jdbc 链接池的拦截器。
    内置的拦截器: org.apache.tomcat.jdbc.pool.interceptor.ConnectionState
    追踪自动提交、只读状态、catalog和事务隔离等级等状态

org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer
追踪打开的statement,当链接被归还时关闭它们.

多个拦截器用;分割,例如:

javapoolProps.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
  • dataSourceJNDI
    指定一个 jndi 做为数据源
  • accessToUnderlyingConnectionAllowed

以上属性当你我没法理解的时候,最好保持默认值。

如下待续。。。

xml 配置 (Use in tomcat)

高级使用 (Advanced usage)

使用加强功能 (Enhanced)

拦截器 (Interceptor)

如何编译 (Build)

tomcat源码svn仓库

本文是笔者翻阅tomcat官网jdbc-pool专栏,并将内容以笔者本身的语言从新组织,能够直接点击[tomcat-jdbc]查看官网

相关文章
相关标签/搜索