2017-06-17 68 views
0

我們使用c3p0 ComboPooledDataSource與Spring JdbcTemplate進行連接池訪問oracle 11g數據庫。經過一段時間後(看起來在短暫的網絡中斷之後),從池中獲取連接的所有請求都將獲得超時異常。直到我們的weblogic服務器重新啓動(不需要重新啓動數據庫服務器)才能解決這個問題。C3P0連接在網絡中斷後才恢復,直到服務器重啓

Caused by: com.mchange.v2.resourcepool.TimeoutException: A client timed out while waiting to acquire a resource from [email protected] -- timeout at awaitAvailable() 
    at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1317) 
    at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557) 
    at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477) 
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525) 

我檢查了數據庫當前會話和c3p0日誌,沒有連接泄漏(只有50個連接使用1550)。 我也注意到,在網絡中斷後,c3p0不會獲得新的連接(acquire_increment增加,但管理連接從50降低到10)。

我們的數據源配置:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 
     <property name="properties" > 
      <props> 
       <prop key="oracle.net.CONNECT_TIMEOUT">20000</prop> 
       <prop key="oracle.jdbc.ReadTimeout">70000</prop> 
      </props> 
     </property> 
     <!-- Connection properties --> 
     <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/> 
     <property name="jdbcUrl" value="jdbc:oracle:thin:@//host:port/db_name"/> 
     <property name="user" value="*****"/> 
     <property name="password" value="*****"/> 
     <!-- Pool properties --> 
     <property name="testConnectionOnCheckout" value="true"/> 
     <property name="checkoutTimeout" value="30000" /> 
     <property name="debugUnreturnedConnectionStackTraces" value="true" /> <!-- Turn this on only for debugging --> 
     <property name="preferredTestQuery" value="select 1 from dual"/> 
     <property name="initialPoolSize" value="3" /> 
     <property name="maxAdministrativeTaskTime" value="30" /> 
     <property name="maxIdleTime" value="600" /> 
     <property name="maxPoolSize" value="1550" /> 
     <property name="maxStatements" value="0" /> <!-- Disable statement pooling --> 
     <property name="maxStatementsPerConnection" value="0" /> <!-- Disable statement pooling --> 
     <property name="minPoolSize" value="5" /> 
     <property name="numHelperThreads" value="15" /> 
     <property name="unreturnedConnectionTimeout" value="600" /> <!-- Should set this for debugging leaks --> 
    </bean> 

我不知道究竟發生了什麼事情。

更新 對不起,編輯的配置(測試是錯誤的,我的問題,但不是我的實際配置文件)

回答

0

有幾件事情:

  1. 你可能不會得到連接測試是你認爲你是。您設置了一個名爲TestConnectionOnCheckout的屬性,但該屬性的名稱爲testConnectionOnCheckout,小寫字母爲t
  2. 您可能會發生連接泄漏。如果你的應用程序凍結了,50是一個奇怪的循環連接數,而1550的一個maxPoolSize可能沒有意義,因爲它比你的後端支持的要高。
  3. 您配置了unreturnedConnectionTimeoutdebugUnreturnedConnectionStackTraces來調試連接泄漏,但您的unreturnedConnectionTimeout時間很長。在事情凍結之前,您必須等待10分鐘,然後才能觀察(在您的日誌中)最終泄露的所有Connections的檢查堆棧痕跡。考慮在你正在調試的時候把它縮小一些,比如30秒,這樣你就可以得到關於連接泄漏的相當好的信息。
  4. 您將properties,userpassword設置爲不同的值。這可能不太好。最終userpassword在JDBC屬性中獲得設置。如果在設置properties屬性之前userpassword已設置,則最終可能會用身份驗證憑據替換屬性對象,並在沒有正確用戶和密碼的情況下發出請求。如果您明確設置properties,考慮的東西像這樣...

    <property name="properties" > 
        <props> 
         <prop key="oracle.net.CONNECT_TIMEOUT">20000</prop> 
         <prop key="oracle.jdbc.ReadTimeout">70000</prop> 
         <prop key="user">*****</prop> 
         <prop key="password">*****</prop> 
        </props> 
    </property> 
    

...所以你可以肯定的是userpassword置位。

c3p0 PooledDataSources在池初始化的INFO處記錄它們的配置。這可能值得一看,並驗證它是你期望看到的配置。

+0

(剛剛更新了一下) –

+0

對於TestConnectionOnCheckout感到抱歉,這是我的問題中的一個錯誤。更新了問題。 –