c3p0數據源的使用初步及Mysql8小時問題解決

原文:http://blog.csdn.net/xby1993/article/details/23707775html

c3p0號稱是java界最好的數據池。java

 

c3p0的配置方式分爲三種,分別是mysql

1.setters一個個地設置各個配置項sql

2.類路徑下提供一個c3p0.properties文件數據庫

3.類路徑下提供一個c3p0-config.xml文件緩存

咱們主要說下c3p0-config.xml配置:tomcat

 

<c3p0-config>服務器

//默認池配置網絡

<default-config>  多線程

<property name="user">root</property>

<property name="password">java</property>

<property name="driverClass">com.mysql.jdbc.Driver</property>

<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc</property>

 

   <property name="initialPoolSize">10</property>

   <property name="maxIdleTime">30</property>

   <property name="maxPoolSize">100</property>

   <property name="minPoolSize">10</property>

 </default-config>

 //命名池配置

 <named-config name="myApp">

<property name="user">root</property>

<property name="password">java</property>

<property name="driverClass">com.mysql.jdbc.Driver</property>

<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc</property>

   <property name="initialPoolSize">10</property>

   <property name="maxIdleTime">30</property>

   <property name="maxPoolSize">100</property>

   <property name="minPoolSize">10</property>

 </named-config>

</c3p0-config>

 

可見c3p0能夠配置在一個應用中使用多個池。換言之可使用多個數據庫。

使用:

//使用默認池:

private static ComboPooledDataSource ds = new ComboPooledDataSource();

//使用命名池

private static ComboPooledDataSource ds = new ComboPooledDataSource("myApp");

基本配置項的介紹:

 

1.基本配置

acquireIncrement

default : 3

鏈接池在無空閒鏈接可用時一次性建立的新數據庫鏈接數

initialPoolSize

default : 3

鏈接池初始化時建立的鏈接數

maxPoolSize

default : 15

鏈接池中擁有的最大鏈接數,若是得到新鏈接時會使鏈接總數超過這個值則不會再獲取新鏈接,而是等待

其餘鏈接釋放,因此這個值有可能會設計地很大

maxIdleTime

default : 0 單位 s

鏈接的最大空閒時間,若是超過這個時間,某個數據庫鏈接尚未被使用,則會斷開掉這個鏈接

若是爲0,則永遠不會斷開鏈接

minPoolSize

default : 3

鏈接池保持的最小鏈接數,後面的maxIdleTimeExcessConnections跟這個配合使用來減輕鏈接池的負載

 

2.管理鏈接池的大小和鏈接的生存時間

maxConnectionAge

default : 0 單位 s

配置鏈接的生存時間,超過這個時間的鏈接將由鏈接池自動斷開丟棄掉。固然正在使用的鏈接不會立刻斷開,而是等待

它close再斷開。配置爲0的時候則不會對鏈接的生存時間進行限制。

maxIdleTimeExcessConnections

default : 0 單位 s

這個配置主要是爲了減輕鏈接池的負載,好比鏈接池中鏈接數由於某次數據訪問高峯致使建立了不少數據鏈接

可是後面的時間段須要的數據庫鏈接數不多,則此時鏈接池徹底沒有必要維護那麼多的鏈接,因此有必要將

斷開丟棄掉一些鏈接來減輕負載,必須小於maxIdleTime。配置不爲0,則會將鏈接池中的鏈接數量保持到minPoolSize。

爲0則不處理。

3.配置鏈接測試:由於鏈接池中的數據庫鏈接頗有多是維持數小時的鏈接,頗有可能由於數據庫服務器的問題,網絡問題等致使實際鏈接已經無效,可是鏈接池裏面的鏈接仍是有效的,若是此時得到鏈接確定會發生異常,因此有必要經過測試鏈接來確認鏈接的有效性。

下面的前三項用來配置如何對鏈接進行測試,後三項配置對鏈接進行測試的時機。

automaticTestTable

default : null

用來配置測試鏈接的一種方式。配置一個表名,鏈接池根據這個表名建立一個空表,

而且用本身的測試sql語句在這個空表上測試數據庫鏈接

這個表只能由c3p0來使用,用戶不能操做,同時用戶配置的preferredTestQuery 將會被忽略。

preferredTestQuery

default : null

用來配置測試鏈接的另外一種方式。與上面的automaticTestTable兩者只能選一。

若是要用它測試鏈接,千萬不要設爲null,不然測試過程會很耗時,同時要保證sql語句中的表在數據庫中必定存在。

connectionTesterClassName

default :  com.mchange.v2.c3p0.impl.DefaultConnectionTester

鏈接池用來支持automaticTestTable和preferredTestQuery測試的類,必須是全類名,就像默認的那樣,

能夠經過實現UnifiedConnectionTester接口或者繼承AbstractConnectionTester來定製本身的測試方法

idleConnectionTestPeriod

default : 0

用來配置測試空閒鏈接的間隔時間。測試方式仍是上面的兩種之一,能夠用來解決MySQL8小時斷開鏈接的問題。由於它

保證鏈接池會每隔必定時間對空閒鏈接進行一次測試,從而保證有效的空閒鏈接能每隔必定時間訪問一次數據庫,將於MySQL

8小時無會話的狀態打破。爲0則不測試。

testConnectionOnCheckin

default : false

若是爲true,則在close的時候測試鏈接的有效性。爲了提升測試性能,能夠與idleConnectionTestPeriod搭配使用,

配置preferredTestQuery或automaticTestTable也能夠加快測試速度。

testConnectionOnCheckout

default : false

性能消耗大。若是爲true,在每次getConnection的時候都會測試,爲了提升性能,

能夠與idleConnectionTestPeriod搭配使用,

配置preferredTestQuery或automaticTestTable也能夠加快測試速度。

4.配置PreparedStatement緩存

maxStatements

default : 0

鏈接池爲數據源緩存的PreparedStatement的總數。因爲PreparedStatement屬於單個Connection,因此

這個數量應該根據應用中平均鏈接數乘以每一個鏈接的平均PreparedStatement來計算。爲0的時候不緩存,

同時maxStatementsPerConnection的配置無效。

maxStatementsPerConnection

default : 0

鏈接池爲數據源單個Connection緩存的PreparedStatement數,這個配置比maxStatements更有意義,由於

它緩存的服務對象是單個數據鏈接,若是設置的好,確定是能夠提升性能的。爲0的時候不緩存。

注意當數據池再也不使用時須要調用close()方法手動關閉它配置舉例:

 

[xml]  view plain  copy
 
  1. 個人c3p0配置實例:  
  2.   
  3. <c3p0-config>  
  4. <!--解決Mysql 8小時問題 -->  
  5. <default-config>  
  6. <property name="automaticTestTable">C3P0Test</property>  
  7. <property name="idleConnectionTestPeriod">60</property>  
  8. <!--設置爲2個小時 -->  
  9. <property name="maxIdleTime">60</property>   
  10. <!--獲取鏈接時測試是否有效 ,消耗較大,不建議使用-->  
  11. <!-- <property name="testConnectionCheckin">true</property> -->  
  12. <!--  -->  
  13. <property name="initialPoolSize">10</property>  
  14. <property name="maxPoolSize">100</property>   
  15. <property name="minPoolSize">10</property>   
  16. <property name="maxStatements">100</property>  
  17.   
  18. <!--獲取鏈接超時毫秒爲單位--->  
  19. <property name="checkoutTimeout">30000</property>  
  20. </default-config>  
  21. </c3p0-config>  

 

 

解決MYSQL 8小時問題

Mysql服務器默認的「wait_timeout」是8小時,也就是說一個connection空閒超過8個小時,Mysql將自動斷開該 connection。這就是問題的所在,在C3P0 pools中的connections若是空閒超過8小時,Mysql將其斷開,而C3P0並不知道該connection已經失效,若是這時有 Client請求connection,C3P0將該失效的Connection提供給Client,將會形成上面的異常。

解決的方法有3種:

   增長wait_timeout的時間。

   減小Connection pools中connection的lifetime。

   測試Connection pools中connection的有效性。

C3P0增長如下配置信息:

   //自動測試的table名稱

   automaticTestTable=C3P0TestTable

   //set to something much less than wait_timeout, prevents connections from going stale。每一個小時測試一次

   idleConnectionTestPeriod = 3600

   //set to something slightly less than wait_timeout, preventing 'stale' connections from being handed out最大空閒時間爲2個小時

   maxIdleTime = 7200

//獲取connnection時測試是否有效

testConnectionOnCheckin = true

 


 

總體說明:

<c3p0-config>

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


 

 

 

補充一點,與c3p0配置無關,可是對於tomcat中配置DBCP很重要。

對於tomcat中的DBCP,也須要解決Mysql 8小時問題,因此須要這樣:

  //set to 'SELECT 1'

  validationQuery = "SELECT 1"

  //set to 'true'

  testWhileIdle = "true"

  //some positive integer

  timeBetweenEvictionRunsMillis = 3600000

  //set to something smaller than 'wait_timeout'

  minEvictableIdleTimeMillis = 18000000

  //if you don't mind a hit for every getConnection(), set to "true"

  testOnBorrow = "true"

參考:http://my.oschina.net/lyzg/blog/55133

http://www.blogjava.net/Alpha/archive/2009/03/29/262789.html

相關文章
相關標籤/搜索