2

スタック オーバーフローには多くの関連する問題がありますが、問題の解決策と正確な理由がまだ明確でないため、これを掲載しています。ここで私の問題を完全に解決し、すべての人に完全に役立つことを願っています

アプリケーションで c3p0、MySQL、hibernate(J PA)、および spring を使用しています。アプリケーションで使用している主な jar ファイルのリストは次のとおりです。

c3p0-0.9.2.jar
mchange-commons-java-0.2.3.3.jar
hibernate-commons-annotations-3.0.0.ga.jar
hibernate-entity manager.jar
hibernate-tools.jar
hibernate-validator-4.0.2.GA.jar
hibernate3.jar
mysql-connector-java-5.1.13-bin.jar

私のpersistent.XMLのc3p0設定は次のようなものです:

<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_period" value="300"/>

ここで、hibernate.c3p0.idle_test_period が hibernate.c3p0.timeout を超えてはならないことをどこかで読みました。私の場合、どちらも同じです。

何かを変更する必要がありますか? どうすればこの問題を解決できますか?

サーバーは数時間 (正確には 8 時間まで) 正常に動作し、次のエラーが発生します。エラーログは次のとおりです。

    Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: 
    Communications link failure
    The last packet successfully received from the server was 35,019,246 milliseconds
     ago.  The last packet sent successfully to the server was 0 milliseconds ago.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at             sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
        at      sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
        at         com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1118)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3055)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2941)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3489)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2113)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568)
        at         com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2113)
        at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2275)
        at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery
    (NewProxyPreparedStatement.java:116)
        at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
        at org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
        at org.hibernate.loader.Loader.doQuery(Loader.java:674)
        at  org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
        at org.hibernate.loader.Loader.doList(Loader.java:2220)
        ... 39 more
    Caused by: java.io.EOFException: Can not read response from server.
    Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
        at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2502)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2952)
        ... 52 more
    ... 39 more
    Caused by: java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3302)
        ... 50 more

ここでは、persistent.xml のスナップショットを示しています:-

<properties>
      <property name="hibernate.connection.username" value="****"/>
      <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
      <property name="hibernate.connection.password" value="***************"/>
      <property name="hibernate.connection.url" value="jdbc:mysql://xxx.xxx.x.xx:3306/projectname?autoReconnect=true"/>
      <!--Connection Pooling c3p0 configuration-->
      <!--Minimum number of JDBC connections in the pool. Hibernate default: 1-->
      <property name="hibernate.c3p0.min_size" value="5"/>
      <!--Maximum number of JDBC connections in the pool. Hibernate default: 100-->
      <property name="hibernate.c3p0.max_size" value="20"/>
      <!--When an idle connection is removed from the pool (in second). Hibernate default: 0, never expire.-->
      <property name="hibernate.c3p0.timeout" value="300"/>
      <!--Number of prepared statements will be cached. Increase performance. Hibernate default: 0 , caching is disable.-->
      <property name="hibernate.c3p0.max_statements" value="50"/>
      <!--idle time in seconds before a connection is automatically validated. Hibernate default: 0-->
      <property name="hibernate.c3p0.idle_test_period" value="300"/>
    </properties>

アプリケーションで接続クラスのシングルトン オブジェクトを使用します。

public static void createConnection() 
{
    if (em != null) 
       {
            Connection.em.clear();
        }
        if (em == null) {
            new Connection();
        } 

前もって感謝します。解決策が得られることを願っています。

--うーん--

4

4 に答える 4

2

シングルトン接続オブジェクトは悪い考えです(少なくとも、並行するマルチクライアントアプリケーションにはあります)。これは確かに接続プールと矛盾します。接続プールは、接続が必要なときにプールから取得し、作業単位が完了するとすぐに[close()を呼び出して]プールに戻す必要があるという哲学です。

現在、シングルトン接続はタイムアウトし、c3p0はそれについて何もできません。接続プールは、接続がプールにチェックインされるときに、接続を管理およびテストします。チェックアウトされると、プールは邪魔にならないようにし、クライアントに干渉しないようにします。

==>そうは言っても、「Connection」クラスがここにあるかどうかは不明です。Connectionに「em」という静的フィールドがあるため、結局はjava.sql.Connectionではないように見えます。したがって、何が起こっているのかを解釈するのは困難です。

大まかに言えば、単一のc3p0データソースが必要であり、必要に応じて接続を取得し、可能な限り迅速にそれらをclose()する必要があります。

表示されているような接続タイムアウトを防ぐには、接続テスト体制にアプローチするのが最善です。最も簡単なアプローチは、設定することです...

hibernate.c3p0.validate=true
hibernate.c3p0.preferredTestQuery=SELECT 1

それが機能するようになったら、testConnectionOnCheckinとidleConnectionTestPeriod(またはhibernate.c3p0.idle_test_period)を使用して、パフォーマンスを少し向上させることができます。http://www.mchange.com/projects/c3p0/#configuring_connection_testingを参照してください

idleConnectionTestPeriod(hibernate.c3p0.idle_test_period)とmaxIdleTime(hibernate.c3p0.timeout)を同じにしても意味がありません。アイドル接続はテストされません。チャンスを得る前に期限切れになります。idleConnectionTestPeriod(hibernate.c3p0.idle_test_period)を設定した場合は、maxIdleTime(hibernate.c3p0.timeout)よりもはるかに短くする必要があります。

幸運を!

于 2013-03-18T11:13:03.090 に答える
0
Caused by: CommunicationsException: Communications link failure

この例外は、データベースに到達できないことを意味します。

データベースに接続できるので、問題があるのではないかと思います

1)その時点でDBサーバーがダウンしている

2)DBサーバーの接続が不足しています。

この例外が発生したときに、他のツール、MySQL Workbenchを使用して、またはコンソールからデータベースに接続してみてください

于 2013-03-18T10:33:38.920 に答える