14

プロダクションコードからこのエラーが発生しました:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: サーバーから正常に受信された最後のパケットは 36940 秒前でした。サーバーに正常に送信された最後のパケットは 36940 秒前で、サーバーが構成した 'wait_timeout' の値よりも長くなっています。この問題を回避するには、アプリケーションで使用する前に接続の有効性を期限切れにするかテストするか、クライアント タイムアウトのサーバー設定値を増やすか、Connector/J 接続プロパティ 'autoReconnect=true' を使用することを検討する必要があります。

そして今、問題をローカルで再現して修正しようとしています。次のように春のコンテキストをセットアップします。

<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?useUnicode=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 ミリ秒前です。

では、これら 2 つのエラーは同じものなのだろうか、それとも異なるものなのだろうか? 私はいくつかの調査を行いましたが、両方のエラーが同じ解決策に至ったようです:プロパティ「testConnectionOnCheckout = true」を使用しています。ただし、c3p0 doc によると、これは非常にコストのかかるチェックです。「idleConnectionTestPeriod」の使用を推奨していますが、私はすでに 120 秒に設定しています。アイドル状態の接続を適切に検証できるようにするには、どの値を使用すればよいですか?

だから私は基本的に2つのことを尋ねています:

  1. 製品コードで発生したエラーを再現するにはどうすればよいですか?
  2. どうすれば修正できますか?

ありがとう!

4

3 に答える 3

3

MySQL と接続プールでも同様の問題がありました。問題は、アイドル タイムアウトが 30 分であることを接続プールに伝えても、データベースは 10 秒後に接続を切断することです。アイドル接続チェック期間は 120 秒であるため、プールが壊れた接続を使用するのに 110 秒弱の時間が残ります。

本番環境では次の設定を使用します。

MySQL:
wait_timeout=75
C3P0:
maxIdleTime=60
idleConnectionTestPeriod=55
于 2009-10-11T20:06:04.880 に答える
0

フェイ - これまでに投稿された情報に基づいて実際に言うことはできません.

既知の問題がある場合に備えて、MySQL/Spring/Hibernate/C3PO/JDBC のバージョン番号を質問に追加することをお勧めします。

製品エラー メッセージは一般的なものであり、多くの根本原因が考えられます。あなたのためのいくつかのリード:

  1. プロダクション エラーは、アプリケーションが完了したときに接続をプールに解放していないことを示している可能性があり、c3p0 が接続をチェックできません。(c3p0 アイドル チェックは、チェックアウトされていない接続にのみ適用できます。)

  2. c3p0 が実際に機能していることを確認します (そうでない場合は、「バニラ」接続を使用している可能性があります)。テストで、(たとえば) MySql wait_timeout=10、アプリケーション スレッド sleep=35、idleConnectionTestPeriod=30 を設定すると、プーリングが機能している場合、例外はなくなるはずです。

  3. アイドル チェックを犠牲にして: デフォルトの getTables() を使用しないことを検討してください。

于 2009-10-06T09:34:27.297 に答える
0

エラーを再現するには、MySQL プロパティで接続タイムアウトを非常に低い値 (2 ミリ秒など) に設定し、処理時間が長いことがわかっているクエリを実行します。プロパティ ファイルを使用して JDBC 接続を設定している場合は、MySQL 接続文字列またはプロパティを介してタイムアウト プロパティを設定できます。これを行う方法の詳細については、特定の jaxax.sql.DataSource 接続に関する Javadocs と MySQL docs を検索できます。

于 2009-10-07T18:45:46.060 に答える