c3p0、dbcp、tomcat jdbc pool 鏈接池區別

查看資料,得知dbcp和c3p0都是單線程的,在高併發的環境下性能會很是低下, 
決定換用tomcat自帶的jdbc-pool,關於jdbc-pool的項目介紹。 
區別參考連接:http://www.open-open.com/lib/view/open1329182303124.htmlhtml

<!--  class="org.apache.tomcat.dbcp.dbcp.BasicDataSource" -->
    <!--  class="org.springframework.jdbc.datasource.DriverManagerDataSource" -->
       <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" parent="c3p0DataSource">

Tomcat 在 7.0 之前的版本都是使用 commons-dbcp 作爲鏈接池的實現,可是 dbcp 飽受詬病,緣由有:java

dbcp 是單線程的,爲了保證線程安全會鎖整個鏈接池 
dbcp 性能不佳 
dbcp 太複雜,超過 60 個類 
dbcp 使用靜態接口,在 JDK 1.6 編譯有問題 
dbcp 發展滯後 
所以不少人會選擇一些第三方的鏈接池組件,例如 c3p0 , bonecp, druid (@wenshao ) 等。mysql

爲此,Tomcat 從 7.0 開始引入一個新的模塊:Tomcat jdbc poolspring

tomcat jdbc pool 近乎兼容 dbcp ,性能更高 
異步方式獲取鏈接 
tomcat jdbc pool 是 tomcat 的一個模塊,基於 tomcat JULI,使用 Tomcat 的日誌框架 
使用 javax.sql.PooledConnection 接口獲取鏈接 
支持高併發應用環境 
超簡單,核心文件只有8個,比 c3p0 還 
更好的空閒鏈接處理機制 
支持 JMX 
支持 XA Connection 
tomcat jdbc pool 的優勢遠不止這些,詳情請看這裏。sql

tomcat jdbc pool 可在 Tomcat 中直接使用,也能夠在獨立的應用中使用。數據庫

推薦使用 
[html] view plain copy print?apache

<!-- JDBC鏈接池 、數據源 -->  

<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource">  
  <property name="driverClassName" value="${jdbc.driverClassName}" />  
  <property name="url" value="${jdbc.url}" />  
  <property name="username" value="${jdbc.username}" />  
  <property name="password" value="${jdbc.password}" />  
  <property name="testWhileIdle" value="true" />  
  <property name="testOnBorrow" value="true" />  
  <property name="testOnReturn" value="false" />  
  <property name="validationQuery" value="SELECT 1" />  
  <property name="validationInterval" value="30000" />  
  <property name="timeBetweenEvictionRunsMillis" value="30000" />  
  <property name="maxActive" value="100" />  
  <property name="minIdle" value="2" />  
  <property name="maxWait" value="10000" />  
  <property name="initialSize" value="4" />  
  <property name="removeAbandonedTimeout" value="60" />  
  <property name="removeAbandoned" value="true" />  
  <property name="logAbandoned" value="true" />  
  <property name="minEvictableIdleTimeMillis" value="30000" />  
  <property name="jmxEnabled" value="true" />  
</bean>

引入Maven依賴: 
[html] view plain copy print?在CODE上查看代碼片派生到個人代碼片 

org.apache.tomcat 
tomcat-jdbc 
7.0.29 


org.apache.tomcat 
tomcat-juli 
7.0.29 數組

tomcat-dbcp與commons-dbcp有什麼區別 
The default database connection pool implementation in Apache Tomcat relies on the libraries from the Apache Commons project. The following libraries are used: 
Commons DBCP 
Commons Pool 
These libraries are located in a single JAR at $CATALINA_HOME/lib/tomcat-dbcp.jar. However, only the classes needed for connection pooling have been included, and the packages have been renamed to avoid interfering with applications. 
以上是tomcat7.x的幫助文檔,大意是tomcat-dbcp.jar包含了commons-dbcp和Commons Pool的內容,固然也只僅僅包含了須要數據庫鏈接的部分,而不是所有。緩存

本文提供了對c3p0與DBCP鏈接池鏈接MySQL數據庫時, 8小時內無請求自動斷開鏈接的解決方案。首先介紹一下我在項目(c3p0鏈接池)中遇到的問題,後面還提供了使用DBCP鏈接池的解決方案。tomcat

基本問題解決 
項目環境: 
Java Web項目框架爲spring MVC+JPA,使用c3p0鏈接池,發佈環境爲Tomcat 7

錯誤描述: 
項目運行一段時間(大概幾個小時)以後訪問時會出現第一次訪問報錯,再次訪問正常的現象,且屢次出現此問題。

報錯日誌:

[plain] view plain copy 在CODE上查看代碼片派生到個人代碼片

org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.TransactionException: JDBC begin transaction failed:   
    at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:428)  
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:372)  
    at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:417)  
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:255)  
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)  
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)  
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)  
    at com.appcarcare.cube.service.UserService
EnhancerByCGLIB
a4429cba.getUserDao(<generated>)  

    at com.appcarcare.cube.servlet.DataCenterServlet$SqlTimer.connectSql(DataCenterServlet.java:76)  
    at com.appcarcare.cube.servlet.DataCenterServlet$SqlTimer.run(DataCenterServlet.java:70)  
    at java.util.TimerThread.mainLoop(Timer.java:555)  
    at java.util.TimerThread.run(Timer.java:505)  
Caused by: javax.persistence.PersistenceException: org.hibernate.TransactionException: JDBC begin transaction failed:   
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)  
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)  

    at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1397)  
    at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:62)  
    at org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(DefaultJpaDialect.java:71)  
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:60)  
    at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:378)  
    ... 11 more  
Caused by: org.hibernate.TransactionException: JDBC begin transaction failed:   
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:76)  
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:160)  

    at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1426)  
    at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:59)  
    ... 14 more  
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure  

The last packet successfully received from the server was 1,836,166 milliseconds ago.  The last packet sent successfully to the server was 29,134 milliseconds ago.  
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)  
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)  
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)  
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)  
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)  
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1117)  
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3567)  
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3456)  

    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3997)  
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2468)  
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2629)  
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2713)  
    at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:5060)  
    at com.mchange.v2.c3p0.impl.NewProxyConnection.setAutoCommit(NewProxyConnection.java:881)  
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:72)  

    ... 17 more  
Caused by: java.net.SocketException: Software caused connection abort: recv failed  
    at java.net.SocketInputStream.socketRead0(Native Method)  
    at java.net.SocketInputStream.read(SocketInputStream.java:150)  
    at java.net.SocketInputStream.read(SocketInputStream.java:121)  
    at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114)  
    at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161)  
    at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189)  
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3014)  
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3467)  
    ... 25 more

緣由分析: 
MySQL服務器默認的「wait_timeout」是28800秒即8小時,意味着若是一個鏈接的空閒時間超過8個小時,MySQL將自動斷開該鏈接,而鏈接池卻認爲該鏈接仍是有效的(由於並未校驗鏈接的有效性),當應用申請使用該鏈接時,就會致使上面的報錯。 
解決方案(解決這個問題的辦法有三種,推薦第二種): 
1. 增長 MySQL 的 wait_timeout 屬性的值 
修改mysql安裝目錄下的配置文件 my.ini文件(若是沒有此文件,複製「my-default.ini」文件,生成「復件 my-default.ini」文件。將「復件 my-default.ini」文件重命名成「my.ini」 ),在文件中設置: 
[plain] view plain copy 在CODE上查看代碼片派生到個人代碼片

wait_timeout=31536000  
interactive_timeout=31536000

這兩個參數的默認值是8小時(60*60*8=28800)。 
注意: 1.wait_timeout的最大值只容許2147483 (24天左右) 
2.修改配置文件爲網上大部分文章所提供的方式,也可使用mysql命令對這兩個屬性進行修改 
mysql命令

  1. 減小鏈接池內鏈接的生存週期 
    減小鏈接池內鏈接的生存週期,使之小於上一項中所設置的wait_timeout 的值。 
    修改 c3p0 的配置文件,在 Spring 的配置文件中設置: 
    [java] view plain copy 在CODE上查看代碼片派生到個人代碼片 


     
  2. 按期使用鏈接池內的鏈接 
    按期使用鏈接池內的鏈接,使得它們不會由於閒置超時而被 MySQL 斷開。 
    修改 c3p0 的配置文件,在 Spring 的配置文件中設置: 
    [java] view plain copy 在CODE上查看代碼片派生到個人代碼片
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">    
<property name="preferredTestQuery" value="SELECT 1"/>    
<property name="idleConnectionTestPeriod" value="18000"/>    
<property name="testConnectionOnCheckout" value="true"/>    
</bean>

知識擴展 
C3P0 
C3P0是一個開放源代碼的JDBC鏈接池,它在lib目錄中與hibernate一塊兒發佈,包括了實現jdbc3和jdbc2擴展規範說明的Connection 和Statement 池的DataSources 對象。 c3p0配置文件

[html] view plain copy 在CODE上查看代碼片派生到個人代碼片

<default-config>   
  <!--當鏈接池中的鏈接耗盡的時候c3p0一次同時獲取的鏈接數。Default: 3 -->   
  <property name="acquireIncrement">3</property>   
  <!--定義在從數據庫獲取新鏈接失敗後重復嘗試的次數。Default: 30 -->   
  <property name="acquireRetryAttempts">30</property>   
  <!--兩次鏈接中間隔時間,單位毫秒。Default: 1000 -->   
  <property name="acquireRetryDelay">1000</property>   
  <!--鏈接關閉時默認將全部未提交的操做回滾。Default: false -->   
  <property name="autoCommitOnClose">false</property>   
  <!--c3p0將建一張名爲Test的空表,並使用其自帶的查詢語句進行測試。若是定義了這個參數那麼   
  屬性preferredTestQuery將被忽略。你不能在這張Test表上進行任何操做,它將只供c3p0測試   
  使用。Default: null-->   
  <property name="automaticTestTable">Test</property>   
  <!--獲取鏈接失敗將會引發全部等待鏈接池來獲取鏈接的線程拋出異常。可是數據源仍有效   
  保留,並在下次調用getConnection()的時候繼續嘗試獲取鏈接。若是設爲true,那麼在嘗試   
  獲取鏈接失敗後該數據源將申明已斷開並永久關閉。Default: false-->   
  <property name="breakAfterAcquireFailure">false</property>   
  <!--當鏈接池用完時客戶端調用getConnection()後等待獲取新鏈接的時間,超時後將拋出   
  SQLException,如設爲0則無限期等待。單位毫秒。Default: 0 -->   
  <property name="checkoutTimeout">100</property>   
  <!--經過實現ConnectionTester或QueryConnectionTester的類來測試鏈接。類名需制定全路徑。   
  Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester-->   
  <property name="connectionTesterClassName"></property>   
  <!--指定c3p0 libraries的路徑,若是(一般都是這樣)在本地便可得到那麼無需設置,默認null便可   
  Default: null-->   
  <property name="factoryClassLocation">null</property>   
  <!--Strongly disrecommended. Setting this to true may lead to subtle and bizarre bugs.   
  (文檔原文)做者強烈建議不使用的一個屬性-->   
  <property name="forceIgnoreUnresolvedTransactions">false</property>   
  <!--每60秒檢查全部鏈接池中的空閒鏈接。Default: 0 -->   
  <property name="idleConnectionTestPeriod">60</property>   
  <!--初始化時獲取三個鏈接,取值應在minPoolSize與maxPoolSize之間。Default: 3 -->   
  <property name="initialPoolSize">3</property>   
  <!--最大空閒時間,60秒內未使用則鏈接被丟棄。若爲0則永不丟棄。Default: 0 -->   
  <property name="maxIdleTime">60</property>   
  <!--鏈接池中保留的最大鏈接數。Default: 15 -->   
  <property name="maxPoolSize">15</property>   
  <!--JDBC的標準參數,用以控制數據源內加載的PreparedStatements數量。但因爲預緩存的statements   
  屬於單個connection而不是整個鏈接池。因此設置這個參數須要考慮到多方面的因素。   
  若是maxStatements與maxStatementsPerConnection均爲0,則緩存被關閉。Default: 0-->   
  <property name="maxStatements">100</property>   
  <!--maxStatementsPerConnection定義了鏈接池內單個鏈接所擁有的最大緩存statements數。Default: 0 -->   
  <property name="maxStatementsPerConnection"></property>   
  <!--c3p0是異步操做的,緩慢的JDBC操做經過幫助進程完成。擴展這些操做能夠有效的提高性能   
  經過多線程實現多個操做同時被執行。Default: 3-->   
  <property name="numHelperThreads">3</property>   
  <!--當用戶調用getConnection()時使root用戶成爲去獲取鏈接的用戶。主要用於鏈接池鏈接非c3p0   
  的數據源時。Default: null-->   
  <property name="overrideDefaultUser">root</property>   
  <!--與overrideDefaultUser參數對應使用的一個參數。Default: null-->   
  <property name="overrideDefaultPassword">password</property>   
  <!--密碼。Default: null-->   
  <property name="password"></property>   
  <!--定義全部鏈接測試都執行的測試語句。在使用鏈接測試的狀況下這個一顯著提升測試速度。注意:   
  測試的表必須在初始數據源的時候就存在。Default: null-->   
  <property name="preferredTestQuery">select id from test where id=1</property>   
  <!--用戶修改系統配置參數執行前最多等待300秒。Default: 300 -->   
  <property name="propertyCycle">300</property>   
  <!--因性能消耗大請只在須要的時候使用它。若是設爲true那麼在每一個connection提交的   
  時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable   
  等方法來提高鏈接測試的性能。Default: false -->   
  <property name="testConnectionOnCheckout">false</property>   
  <!--若是設爲true那麼在取得鏈接的同時將校驗鏈接的有效性。Default: false -->   
  <property name="testConnectionOnCheckin">true</property>   
  <!--用戶名。Default: null-->   
  <property name="user">root</property>   
  在Hibernate(spring管理)中的配置:   
  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">   
  <property name="driverClass"><value>oracle.jdbc.driver.OracleDriver</value></property>   
  <property name="jdbcUrl"><value>jdbc:oracle:thin:@localhost:1521:Test</value></property>   
  <property name="user"><value>Kay</value></property>   
  <property name="password"><value>root</value></property>   
  <!--鏈接池中保留的最小鏈接數。-->   
  <property name="minPoolSize" value="10" />   
  <!--鏈接池中保留的最大鏈接數。Default: 15 -->   
  <property name="maxPoolSize" value="100" />   
  <!--最大空閒時間,1800秒內未使用則鏈接被丟棄。若爲0則永不丟棄。Default: 0 -->   
  <property name="maxIdleTime" value="1800" />   
  <!--當鏈接池中的鏈接耗盡的時候c3p0一次同時獲取的鏈接數。Default: 3 -->   
  <property name="acquireIncrement" value="3" />   
  <property name="maxStatements" value="1000" />   
  <property name="initialPoolSize" value="10" />   
  <!--每60秒檢查全部鏈接池中的空閒鏈接。Default: 0 -->   
  <property name="idleConnectionTestPeriod" value="60" />   
  <!--定義在從數據庫獲取新鏈接失敗後重復嘗試的次數。Default: 30 -->   
  <property name="acquireRetryAttempts" value="30" />   
  <property name="breakAfterAcquireFailure" value="true" />   
  <property name="testConnectionOnCheckout" value="false" />   
  </bean>

  ########################### 
  ### C3P0 Connection Pool### 
  ########################### 
 

 #hibernate.c3p0.max_size 2   
  #hibernate.c3p0.min_size 2   
  #hibernate.c3p0.timeout 5000   
  #hibernate.c3p0.max_statements 100   
  #hibernate.c3p0.idle_test_period 3000   
  #hibernate.c3p0.acquire_increment 2   
  #hibernate.c3p0.validate false   
  在hibernate.cfg.xml文件裏面加入以下的配置:   
  <!-- 最大鏈接數 -->   
  <property name="hibernate.c3p0.max_size">20</property>   
  <!-- 最小鏈接數 -->   
  <property name="hibernate.c3p0.min_size">5</property>   
  <!-- 得到鏈接的超時時間,若是超過這個時間,會拋出異常,單位毫秒 -->   
  <property name="hibernate.c3p0.timeout">120</property>   
  <!-- 最大的PreparedStatement的數量 -->   
  <property name="hibernate.c3p0.max_statements">100</property>   
  <!-- 每隔120秒檢查鏈接池裏的空閒鏈接 ,單位是秒-->   
  <property name="hibernate.c3p0.idle_test_period">120</property>   
  <!-- 當鏈接池裏面的鏈接用完的時候,C3P0一下獲取的新的鏈接數 -->   
  <property name="hibernate.c3p0.acquire_increment">2</property>   
  <!-- 每次都驗證鏈接是否可用 -->   
  <property name="hibernate.c3p0.validate">true</property>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

使用DBCP鏈接池時出現MySql 8小時斷開鏈接的解決方法 
修改l配置文件: 
修改以下:

[html] view plain copy 在CODE上查看代碼片派生到個人代碼片

<data-sources>  
        <data-source key="org.apache.struts.action.DATA_SOURCE"                             type="org.apache.commons.dbcp.BasicDataSource">  
        <set-property property="driverClassName" value="com.mysql.jdbc.Driver" />  
        <set-property property="description" value="wjjg" />  
        <set-property property="url" value="jdbc:mysql://localhost/wjjg?useUnicode=true&characterEncoding=GB2312" />  
        <set-property property="password" value="12345678" />  
        <set-property property="username" value="wjjg" />  
        <set-property property="maxActive" value="10" />  
        <set-property property="maxIdle" value="60000" />  
        <set-property property="maxWait" value="60000" />  
        <set-property property="defaultAutoCommit" value="true" />  
        <set-property property="defaultReadOnly" value="false" />    
        <set-property property="testOnBorrow" value="true"/>  
        <set-property property="validationQuery" value="select 1"/>  
</data-source>
其中testOnBorrow 和 validationQuery 很重要。

testOnBorrow的意思是從數據庫鏈接池中取得鏈接時,對其的有效性進行檢查。

validationQuery 是用來檢查的SQL語句,「select 1」執行較快,是一個不錯的檢測語句。

回顧 
當測試人員反映到這個問題的時候,很快就鎖定了Mysql八小時的問題,可是解決方案卻費了我不小功夫,先是考慮到修改mysql配置文件確定是不太合理的,棄之。

而後想了一下在一個servlet中寫了個定時器,讓它每兩小時查一下數據庫,運行了幾天發現問題仍然存在,將定時器間隔時間修改成30分鐘、3分鐘仍然無濟於事,異常照常出現,棄之。

在網上搜了一下解決方案也挺多,把

[java] view plain copy 在CODE上查看代碼片派生到個人代碼片

<set-property property="testOnBorrow" value="true"/>  
        <set-property property="validationQuery" value="select 1"/>

寫入到配置文件中,運行報錯,說bean中沒有這兩個屬性,查看了一下原來是我用的c3p0鏈接池,而這個解決方案是針對DBCP鏈接池的。

最後在配置文件中,添加了

[java] view plain copy 在CODE上查看代碼片派生到個人代碼片

<property name="maxIdleTime"value="1800"/>

成功解決了問題。

相關問題解決

用數據庫鏈接池解決org.hibernate.exception.JDBCConnectionException:could not execute query 
數據庫鏈接池解決

最近的一個項目在Hibernate使用C3P0的鏈接池,數據庫爲Mysql。開發測試沒有問題,在運行中每一個一段長的空閒時間就出現異常: 
C3P0的鏈接池

本身的項目超時與數據庫失去鏈接,線上是120s超時就沒有鏈接採用的是這個配置

<!-- 數據源定義 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="${COLLECTION_JDBC_URL}" />
        <property name="username" value="${COLLECTION_JDBC_USERNAME}" />
        <property name="password" value="${COLLECTION_JDBC_PASSWORD}" />

        <!-- 最大活動鏈接:鏈接池在同一時間可以分配的最大活動鏈接的數量, 若是設置爲非正數則表示不限制 -->
        <property name="maxActive" value="#{env['jdbcMaxActive'] ?: 20}" />
        <!-- 最大空閒鏈接:鏈接池中允許保持空閒狀態的最大鏈接數量,超過的空閒鏈接將被釋放,若是設置爲負數表示不限制 -->
        <property name="maxIdle" value="#{env['jdbcMaxIdle'] ?: 10 }" />
        <!-- 最小空閒鏈接:鏈接池中允許保持空閒狀態的最小鏈接數量,低於這個數量將建立新的鏈接,若是設置爲0則不建立 -->
        <property name="minIdle" value="#{env['jdbcMinIdle'] ?: 2 }" />
        <!-- 初始化鏈接:鏈接池啓動時建立的初始化鏈接數量 -->
        <property name="initialSize" value="#{env['jdbcInitialSize'] ?: 20}" />
        <!-- 最大等待時間:當沒有可用鏈接時,鏈接池等待鏈接被歸還的最大時間(以毫秒計數),超過期間則拋出異常,若是設置爲-1表示無限等待 -->
        <property name="maxWait" value="#{env['jdbcMaxWait'] ?: 10000 }" />
        <!-- 指明是否在從池中取出鏈接前進行檢驗,若是檢驗失敗,則從池中去除鏈接並嘗試取出另外一個 注意: 設置爲true後若是要生效,validationQuery參數必須設置爲非空字符串 -->
        <property name="testOnBorrow" value="true" />
        <!-- 進行returnObject對返回的connection進行validateObject校驗 -->
        <property name="testOnReturn" value="#{env['jdbcTestOnReturn']?: false}" />
        <property name="validationQuery" value="select 1" />
        <property name="validationQueryTimeout" value="#{env['jdbcValidationQueryTimeout'] ?: 1}" />
        <!-- 空閒時是否進行驗證,檢查對象是否有效,默認爲false -->
        <property name="testWhileIdle" value="#{env['jdbcTestWhileIdle']?: true}" />
        <!-- 在空閒鏈接回收器線程運行期間休眠的時間值,以毫秒爲單位.若是設置爲非正數,則不運行空閒鏈接回收器線程 -->
        <property name="timeBetweenEvictionRunsMillis" value="#{env['jdbcTimeBetweenEvictionRunsMillis']?: 600000}" />
        <!-- 鏈接在池中保持空閒而不被空閒鏈接回收器線程(若是有)回收的最小時間值,單位毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="#{env['jdbcMinEvictableIdleTimeMillis'] ?: 600000}" />
        <!-- 表明每次檢查連接的數量,建議設置和maxActive同樣大,這樣每次能夠有效檢查全部的連接 -->
        <property name="numTestsPerEvictionRun" value="#{env['jdbcMaxActive'] ?: 20}" />
        <property name="removeAbandoned" value="#{env['jdbcRemoveAbandoned']?: true}" />
        <property name="removeAbandonedTimeout" value="#{env['jdbcRemoveAbandonedTimeout']?: 300}" />
        <property name="logAbandoned" value="#{env['jdbcLogAbandoned']?: true}" />
    </bean>

dbcp類型,因爲不讓修改

wait_timeout=31536000  
interactive_timeout=31536000
  • 1
  • 2

也沒法定位問題,最後

<!-- 這裏定義JPA相關配置。整體上來講,這裏使用以Hibernate爲Provider的JPA2.0方案,使用Spring來進行集成,不依賴於容器的JPA實現。 -->
    <bean id="batchDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="${COLLECTION_JDBC_URL}" />
        <property name="username" value="${COLLECTION_JDBC_USERNAME}" />
        <!-- <property name="password" value="#{rsautilManager.decurpt(env['decurpt'] ?:'0',env['jdbcPassword'])}" /> -->
        <property name="password" value="${COLLECTION_JDBC_PASSWORD}" />

        <property name="initialSize" value="3" />   
        <property name="minIdle" value="3" />
        <property name="maxActive" value="20" />
        <property name="maxWait" value="5000" />

        <!-- 心跳檢測時間線程,會休眠timeBetweenEvictionRunsMillis時間,而後只對(沒有borrow的線程 減去 minIdle)的線程進行檢查,若是空閒時間大於minEvictableIdleTimeMillis則進行close -->
        <property name="timeBetweenEvictionRunsMillis" value="90000" />
        <property name="minEvictableIdleTimeMillis" value="1800000" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />
        <property name="testWhileIdle" value="true" />
        <!-- testWhileIdle必須設置爲true,在獲取到鏈接後,先檢查testOnBorrow,而後再斷定testwhileIdle,若是鏈接空閒時間大於timeBetweenEvictionRunsMillis,則會進行心跳檢測。 -->
        <!-- 不須要配置validationQuery,若是不配置的狀況下會走ping命令,性能更高。 -->
        <!-- 鏈接保存在數組裏面,獲取鏈接的時候,獲取數組的最後一位。在timeBetweenEvictionRunsMillis時是從前日後進行檢查鏈接的有效性。 -->

最後更換鏈接池類型而且配置後再也沒有出現斷開不能重連的狀況

相關文章
相關標籤/搜索