當前位置:首頁 > 資訊 > info6 > 正文

c3p0、dbcp、tomcat jdbc pool 連接池區別(推薦使用jdbc pool)

發表于: 2017-04-05   作者:chenaini119   來源:轉載   瀏覽:
摘要: 查看資料,得知dbcp和c3p0都是單線程的,在高并發的環境下性能會非常低下,決定換用tomcat自帶的jdbc-pool,關于jdbc-pool的項目介紹。區別參考鏈接:http://www.open-open.com/lib/view/open1329182303124.html Tomcat在7.0以前的版本都是使用commons-dbcp做為連接池的實現,但是dbcp飽受詬病,原因有:d

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

   <!-- 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 飽受詬病,原因有:

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

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

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

tomcat jdbc pool 可在 Tomcat 中直接使用,也可以在獨立的應用中使用。

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

<!-- 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連接池的解決方案。

基本問題解決
項目環境:
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>  

使用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 

也無法定位問題,最后

<!-- 這里定義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時是從前往后進行檢查連接的有效性。 -->

最后更換連接池類型并且配置后再也沒有出現斷開不能重連的情況

c3p0、dbcp、tomcat jdbc pool 連接池區別(推薦使用jdbc pool)

版權所有 IT知識庫 CopyRight ? 2009-2015 IT知識庫 IT610.com , All Rights Reserved. 京ICP備09083238號
广东25选5开奖结果