close

  在Spring裡配置c3p0有時出現被關閉Connection的Issue,與少了c3p0.idle_test_period屬性有關。c3p0.timeout是指等多久逾時而connection被destroy,而c3p0.idle_test_period則是間隔多久去執行destroy connection的動作。

  另外有意外收穫出自http://www.blogjava.net/willpower88/archive/2007/01/10/92928.html。作者指網上流行的c3p0在Spring配置大多錯誤,內容如下:<property name="driverClass"><value>${jdbc.driverClassName}</value></property>
<property name="jdbcUrl"><value>${jdbc.url}</value></property>              
<property name="user"><value>${jdbc.username}</value></property>
<property name="password"><value>${jdbc.password}</value></property>

<property name="properties">
          <props>             
              <prop key="c3p0.minPoolSize">1</prop>
              <prop key="c3p0.maxPoolSize">10</prop>
              <prop key="c3p0.maxIdleTime">1800</prop>             
              <prop key="c3p0.acquireIncrement">2</prop>
              <prop key="c3p0.maxStatements">0</prop>
                    <prop key="c3p0.initialPoolSize">2</prop>
              <prop key="c3p0.idleConnectionTestPeriod">1800</prop>
              <prop key="c3p0.acquireRetryAttempts">30</prop>
              <prop key="c3p0.breakAfterAcquireFailure">true</prop>
              <prop key="c3p0.testConnectionOnCheckout">true</prop>
              <prop key="user">root</prop>
              <prop key="password">999999</prop>
          </props>
</property>

正確的如下:

<property name="driverClass"><value>${jdbc.driverClassName}</value></property>
<property name="jdbcUrl"><value>${jdbc.url}</value></property>              
<property name="user"><value>${jdbc.username}</value></property>
<property name="password"><value>${jdbc.password}</value></property>
<property name="minPoolSize"><value>1</value></property>
<property name="maxPoolSize"><value>20</value></property>
<property name="maxIdleTime"><value>1800</value></property>
<property name="acquireIncrement"><value>2</value></property>
<property name="maxStatements"><value>0</value></property>
<property name="initialPoolSize"><value>2</value></property>
<property name="idleConnectionTestPeriod"><value>1800</value></property>
<property name="acquireRetryAttempts"><value>30</value></property>
<property name="breakAfterAcquireFailure"><value>true</value></property>
<property name="testConnectionOnCheckout"><value>false</value></property>

此外,c3p0.idle_test_period與上述的c3p0.idleConnectionTestPeriod或idleConnectionTestPeriod同義。


JBoss預設有c3p0的MBean的支援,若也在Spring配置c3p0並在JBoss下運行,常有類似[A C3P0Registry mbean is already registered]的錯誤。根據網路所找到的解法是:

在WEB-INF/classes目錄下新增一個c3p0.properties檔案,該檔內容如下:

com.mchange.v2.c3p0.management.ManagementCoordinator=com.mchange.v2.c3p0.management.NullManagementCoordinator

如此便可讓JBoss的c3p0 MBean無作用。


c3p0遇有一個問題,有時會出現如下的exception。

com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@cc2061 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@cc2061 -- APPARENT DEADLOCK!!! Complete Status:

這時c3p0的配置可以設置max_statements為0


c3p0的其它參數問題, 出自"http://cloudtu.blogspot.com/2007/05/c3p0-connection-pool.html"

1. Hibernate設定檔的設置方式
c3p0.min_size 設為 10   --> 離峰時間所保持的connection數,取max_size一半是經驗值,甚至可以設為1,因為設為10表示至少這10個connection在系統shutdown前永不被close。
c3p0.max_size 設為 35  -->  低於DB的max connections, 如MySQL預設100. (有很大一部份是某一段時間內的使用者量太高所導致;當c3p0要把連線從DB中release時,User又進系統了,結果就是連線給你一路追加。)
c3p0.acquire_increment(指達到max_size的用量後一次可以再追加多少的連線數) 設為 0,後來查了官方文件對此屬性的定義,英文原文如下:Determines how many connections at a time c3p0 will try to acquire when the pool is exhausted。應非刪節字所述,the pool係指目前所存在connections被耗盡,並非達到max_size,是故特此糾正為1,而追加的連線數不會超出max_size。
c3p0.max_statements 設為 0 (這個一定要設成0,不然Connection Pool會常出現DeadLock的Error,在Hibernate官方forum上查了一下,這問題"似乎"是c3p0本身的bug)
c3p0.timeout(單位為秒) 設為 300
c3p0.idle_test_period(單位為秒,指多久要去Check一次是否有connecion被閒置不用) 設為 100


2.如果只是單純的使用c3p0,不跟Hibernate綁在一起,參數設定則是下面這樣
minPoolSize 設為 10
maxPoolSize 設為 35
acquireIncrement 設為 1  <--- modify at 2009/3/27
maxStatements 設為 0
maxIdleTime 設為 300
idleConnectionTestPeriod 設為 100


2009-3-19 C3P0又出現一個問題,如下的Exception:

org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: An SQLException was provoked by the following failure: com.mchange.v2.resourcepool.ResourcePoolException: Attempted to use a closed or broken resource pool
Caused by:
java.sql.SQLException: An SQLException was provoked by the following failure: com.mchange.v2.resourcepool.ResourcePoolException: Attempted to use a closed or broken resource pool

經Google大神裁示,應該再加以下的property,特別是false的部份。

<property name="acquireRetryAttempts">
    <value>30</value>
</property>
<property name="acquireRetryDelay">
    <value>100</value>
</property>
<property name="breakAfterAcquireFailure">
    <value>false</value>
</property>

[2009/3/27]

後來有注意到一個有趣的現象,當breakAfterAcquireFailure為true時,是丟出上述Excetpion沒錯;而改成false,則是不斷的出現另一個Exception,如下:

org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!
這錯誤是我設錯jdbc連線資訊所致,因為breakAfterAcquireFailure為false,就不斷的retry。這表示什麼,jdbc設錯一開始不會被發現,而是先被丟出[Attempted to use a closed or broken resource pool]的Exception。

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 Jemmy 的頭像
    Jemmy

    Jemmy Walker

    Jemmy 發表在 痞客邦 留言(2) 人氣()