1

Web アプリケーション (NO Spring) で c3p0 と組み合わせて Hibernate を使用しています。一晩で、データベース接続 (または少なくとも 1 つ) がタイムアウトしたように見え、翌日パイプ破損の例外が発生します。
以下は、私がプロジェクトに使用している構成です。

    <hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/**********?autoReconnect=true</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
        <property name="hibernate.connection.username">********</property>
        <property name="hibernate.connection.password">********</property>
        <property name="hibernate.show_sql">false</property>
        <property name="hibernate.globally_quoted_identifiers">true</property>
        <property name="hibernate.current_session_context_class">thread</property>
        <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
        <property name="hibernate.connection.autocommit">false</property>
        <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>

        <property name="hibernate.c3p0.min_size">5</property>
        <property name="hibernate.c3p0.max_size">25</property>
        <property name="hibernate.c3p0.timeout">300</property>
        <property name="hibernate.c3p0.max_statements">50</property>
        <property name="hibernate.c3p0.idle_test_period">60</property>
        <property name="hibernate.c3p0.acquire_increment">1</property>
        <property name="hibernate.c3p0.acquireRetryAttempts">5</property>
        <property name="hibernate.c3p0.acquireRetryDelay">250</property>
        <property name="hibernate.c3p0.preferredTestQuery">select 1;</property>
        <property name="hibernate.c3p0.validate">true</property>
        <property name="hibernate.c3p0.testConnectionOnCheckout">true</property>
        <property name="hibernate.c3p0.testConnectionOnCheckin">true</property>
    </session-factory>
</hibernate-configuration>

私が得ている例外は次のようになります:

    サーバーから正常に受信された最後のパケットは、56,974,967 ミリ秒前でした。
    サーバーに正常に送信された最後のパケットは、56,974,967 ミリ秒前です。は
    「wait_timeout」のサーバー構成値よりも長い。どちらかを検討する必要があります
    アプリケーションで使用する前に、接続の有効期限が切れたりテストされたりするため、増加します
    クライアントのタイムアウト用にサーバーが構成した値、または Connector/J 接続を使用する
    プロパティ 'autoReconnect=true' を設定して、この問題を回避してください。
    org.hibernate.exception.JDBCConnectionException: 最後のパケットが正常に受信されました
    サーバーからの送信は 56,974,967 ミリ秒前でした。に正常に送信された最後のパケット
    サーバーは 56,974,967 ミリ秒前でした。サーバーの構成値よりも長い
    「wait_timeout」の。期限切れおよび/または接続のテストを検討する必要があります
    アプリケーションで使用する前に有効性を高め、サーバーの構成値を増やします
    クライアントのタイムアウト、または Connector/J 接続プロパティ「autoReconnect=true」を使用して
    この問題を回避してください。

ここでの問題は、プロパティ autoReconnect=true を使用していて、接続の有効性をテストしていることです。(c3p0 構成を参照してください。) c3p0 構成がロードされていることはほぼ確実です。標準出力ログに次のように表示されるからです。

    2014 年 4 月 8 日 10:57:13 AM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
    情報: c3p0 プールを初期化しています... com.mchange.v2.c3p0.PoolBackedDataSource@f79fb235 [
    connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@4e20d034 [
    acquireIncrement -> 1、acquireRetryAttempts -> 5、acquireRetryDelay -> 250、autoCommitOnClose ->
    false、automaticTestTable -> null、breakAfterAcquireFailure -> false、checkoutTimeout -> 0、
    connectionCustomizerClassName -> null、connectionTesterClassName ->
    com.mchange.v2.c3p0.impl.DefaultConnectionTester、debugUnreturnedConnectionStackTraces -> false、
    factoryClassLocation -> null、forceIgnoreUnresolvedTransactions -> false、identityToken ->
    ph9ube91hyyxjw1mgbhpo|709689fb、idleConnectionTestPeriod -> 60、initialPoolSize -> 3、
    maxAdministrativeTaskTime -> 0、maxConnectionAge -> 0、maxIdleTime -> 300、
    maxIdleTimeExcessConnections -> 0、maxPoolSize -> 25、maxStatements -> 50、maxStatementsPerConnection
     -> 0、minPoolSize -> 5、nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@a1ca3a3 [
    説明 -> null、driverClass -> null、factoryClassLocation -> null、identityToken ->
    ph9ube91hyyxjw1mgbhpo|24bbab7, jdbcUrl -> jdbc:mysql://localhost:3306/********?autoReconnect=true,
    プロパティ -> {user=******, password=******, autocommit=false} ], preferredTestQuery -> 1 を選択;,
    propertyCycle -> 0、testConnectionOnCheckin -> true、testConnectionOnCheckout -> true、
    unreturnedConnectionTimeout -> 0、usesTraditionalReflectiveProxies -> false; userOverrides: {} ],
    dataSourceName -> null、factoryClassLocation -> null、identityToken -> ph9ube91hyyxjw1mgbhpo|fedb05d、
     numHelperThreads -> 3 ]

例外の壊れたパイプ部分は次のとおりです。

    原因: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: サーバーから正常に受信された最後のパケットは、56,974,967 ミリ秒前でした。サーバーに正常に送信された最後のパケットは、56,974,967 ミリ秒前です。'wait_timeout' のサーバー構成値よりも長くなっています。この問題を回避するには、アプリケーションで使用する前に接続の有効性を期限切れにするかテストするか、クライアント タイムアウトのサーバー設定値を増やすか、Connector/J 接続プロパティ 'autoReconnect=true' を使用することを検討する必要があります。
        sun.reflect.NativeConstructorAccessorImpl.newInstance0(ネイティブメソッド)
        sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:57) で
        sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:45) で
        java.lang.reflect.Constructor.newInstance (Constructor.java:525) で
        com.mysql.jdbc.Util.handleNewInstance (Util.java:411) で
        com.mysql.jdbc.SQLError.createCommunicationsException (SQLError.java:1116) で
        com.mysql.jdbc.MysqlIO.send (MysqlIO.java:3851) で
        com.mysql.jdbc.MysqlIO.sendCommand (MysqlIO.java:2471) で
        com.mysql.jdbc.MysqlIO.sqlQueryDirect (MysqlIO.java:2651) で
        com.mysql.jdbc.ConnectionImpl.execSQL (ConnectionImpl.java:2683) で
        com.mysql.jdbc.PreparedStatement.executeInternal (PreparedStatement.java:2144) で
        com.mysql.jdbc.PreparedStatement.executeQuery (PreparedStatement.java:2310) で
        com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery (NewProxyPreparedStatement.java:76) で
        sun.reflect.GeneratedMethodAccessor35.invoke (不明なソース) で
        sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) で
        java.lang.reflect.Method.invoke(Method.java:601) で
        org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation (AbstractStatementProxyHandler.java:122) で
        ... 23以上
    原因: java.net.SocketException: 壊れたパイプ
        java.net.SocketOutputStream.socketWrite0 (ネイティブ メソッド) で
        java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109) で
        java.net.SocketOutputStream.write(SocketOutputStream.java:153) で
        java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) で
        java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) で
        com.mysql.jdbc.MysqlIO.send (MysqlIO.java:3832) で
        ... 33 以上

インターネットで見つけたものに基づいて、次のことを試しました。

  • 接続 URL に autoReconnect=true を追加 (使用しようとした後も接続が切断されているため、再接続が行われていないように見えることに注意してください)
  • c3p0 構成への testConnectionOnCheckout と testConnectionOnCheckin の追加
  • c3p0 構成への idle_test_period と preferredTestQuery の追加

そして、何も機能していないようです。この問題の原因について何か考えている人はいますか?

4

1 に答える 1

2

だから、いくつかのスキャッタショットのアイデア:

にエラーがありますpreferredTestQuery。「SELECT 1;」ではなく「SELECT 1」にする必要があります。これが問題である場合、それに関する例外が表示されると思います (チェックアウトはすべて失敗します) が、それを修正する価値はあります。

[使用している c3p0 のバージョンは? 危険を冒してでも最新の MySQL ドライバーを使用している場合は、最新のプレリリース (現在は c3p0-0.9.5-pre8) を使用してみてください。設定は一切行わないpreferredTestQueryでください。最新バージョンでは、テスト用に JDBC4 Connection.isValid() をサポートしています。]

もう 1 つの可能性は、アプリケーションが接続を開いた (チェックアウトした) 状態を非常に長い時間保持する場合があることです。最終的にアプリケーションは Connection に対して Statement を実行しようとするため、これは Connection リークではありません。ただし、アプリケーションがこれを行う場合、クライアントが使用している間は c3p0 が接続をテストしないため、接続がアイドル状態になる可能性があるため、表示されているものが表示されます。(トランザクションの途中でautoReconnectが機能しないことを除いて、なぜ autoReconnect が役に立たないのかわかりませんか? )長すぎるチェックアウトの例外を閉じて、問題の診断を試みてください。

問題を解決したい (そして問題を理解することにあまり関心がない) 場合は、c3p0 のmaxConnectionAgemaxIdleTimeを設定してみてください。これらを大きな値に設定しても、これらの設定がパフォーマンスに大きな影響を与えることはありません。(おそらく 7200 秒、つまり 2 時間ですが、~1800 秒を超えても問題ありません。) これらの設定 (特に maxConnectionAge) は、問題のある接続が上記のように開いたままプールからチェックアウトされていない限り、非常に簡単です。とても長い間。[クライアントの下からチェックアウトされた Connection を close() する唯一の c3p0 設定はunreturnedConnectionTimeout.]

幸運を!

于 2014-04-09T12:55:04.797 に答える