2009-10-02 58 views
14

我從生產代碼此錯誤:重現com.mysql.jdbc.exceptions.jdbc4.CommunicationsException與Spring的安裝,休眠和C3P0

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException : 的最後一個數據包成功地接收 從服務器was36940秒 年前故去成功發送 到服務器最後一個分組被36940秒前, ,其長於「WAIT_TIMEOUT」的服務器 配置的值。 你應該考慮要麼到期 和/或測試連接有效性 使用前在應用程序中, 增加服務器的客戶端超時配置 值,或使用 連接器/ J連接屬性 「autoReconnect的=真」,以避免這種 問題。

現在我試圖在本地重現問題並修復它。我設置Spring上下文如下:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
    destroy-method="close" p:driverClass="com.mysql.jdbc.Driver" 
    p:jdbcUrl="jdbc:mysql://localhost:3306/test?userUnicode=yes&amp;characterEncoding=UTF-8&amp" 
    p:idleConnectionTestPeriod="120" p:initialPoolSize="1" p:maxIdleTime="1800" 
    p:maxPoolSize="1" p:minPoolSize="1" p:checkoutTimeout="1000" 

/> 

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="hibernateProperties"> 
     <value> 
      hibernate.connection.provider_class = org.hibernate.connection.C3P0ConnectionProvider 
      hibernate.dialect=org.hibernate.dialect.MySQL5Dialect 
      hibernate.default_schema=platform_server_original 
      hibernate.show_sql=false 
     </value> 
    </property> 
    <property name="mappingResources"> 
     <list> 
      <value>sometables.hbm.xml</value> 
     </list> 
    </property> 
</bean> 

然後我把我的MySQL WAIT_TIMEOUT至10秒,然後運行我的測試,這基本上是打開一個連接,做一個查詢,關閉它,所以它返回到池,然後將線程休眠15秒,然後再次打開連接,然後再次執行查詢,以便它斷開。不過,我只得到了類似的錯誤:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: 通信鏈路故障

末向服務器發送數據包是16 毫秒前。

所以我想知道這兩個錯誤是一樣的,還是不一樣?我做了一些研究,似乎這兩個錯誤來到了相同的解決方案:使用屬性「testConnectionOnCheckout =真」。但是,根據c3p0 doc,這是一個非常昂貴的檢查。它建議使用「idleConnectionTestPeriod」的,但我已經設置,爲120秒。我應該使用什麼值才能正確驗證空閒連接?

所以我基本上是問兩兩件事:1。 我怎麼重現我在生產代碼中得到了錯誤? 2.我該如何解決?

謝謝!

+0

你從生產最初的錯誤是在談論超過10小時的一段時間,當連接被檢查出系統首次當發生在早上使用?難道你不能只是將最小池大小設置爲0,或者通過JXB公開池並在工作日開始前將其清除? – SteveD 2009-10-05 19:32:51

+0

@菲 - 你解決了嗎?有興趣知道結果是什麼。 – 2009-10-31 01:34:29

+1

我最終使用了以下2個屬性: testConnectionOnCheckout =「true」 preferredTestQuery =「select 1」 不是最優化的解決方案,但它至少解決了問題。 – fei 2009-11-04 18:19:27

回答

0

飛 - 可能是幾件事情之一,基於到目前爲止張貼的信息真的不能說。

建議你添加MySQL /春/休眠/ C3PO/JDBC版本號你的問題,如果有一個已知的問題在那裏。

生產錯誤消息是一個常見的一種,有許多可能的根本原因。一些線索給你:

  1. 生產錯誤可能表示 您的應用程序是不是 時用它做,防止 C3P0從檢查它釋放連接回 池。(該C3P0 空閒檢查只能應用於 未檢查出連接)。

  2. 檢查C3P0是真正的工作 (您可能正在使用「香草」 連接,如果沒有)。在您的測試, 如果設置(例如)MySql的 WAIT_TIMEOUT = 10,應用程序線程 睡眠= 35,和 idleConnectionTestPeriod = 30,如果 池工作時,異常 應該消失。

  3. 在待機檢查的費用: 考慮不使用默認 的getTables() - 可能設置 preferredTestQuery的東西便宜(-er) 'SELECT 1' 也許爲MySQL?

0

要重現你的錯誤,在你的MySQL屬性中設置您的連接超時,以非常低的值,即2毫秒,並運行已知有很長的處理時間的查詢。如果您使用屬性文件來設置JDBC連接,則可以在MySQL連接字符串中或通過屬性設置timeout屬性。您可以在特定的jaxax.sql.DataSource連接上查找Javadoc,並查看關於如何執行此操作的細節的MySQL文檔。

+1

MySQL的wait_timeout值是秒而不是毫秒。所以它不可能將其設置爲2ms? – 2012-02-23 13:46:28

3

我有類似的問題與MySQL和連接池。問題是您告訴連接池空閒超時時間爲30分鐘,但數據庫在10秒後切斷連接。由於您的閒置連接檢查週期爲120秒,因此游泳池使用斷開的連接時會留下少許110秒的時間!

我會使用生產以下設置:

MySQL: 
wait_timeout=75 
C3P0: 
maxIdleTime=60 
idleConnectionTestPeriod=55