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]查看官網

相關文章
相關標籤/搜索