web-dev-qa-db-ja.com

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:接続が閉じられた後、操作は許可されません

私はアプリケーションを構築し、ローカルに展開しました...そしてそれは完璧に機能していました。リモートサーバーに展開し、件名に記載されている例外の取得を開始しました。ファイアウォールの問題が原因ではありません。

hibernate.xmlを変更して、localhostではなくIPアドレスを介して接続し、ローカルにデプロイされたアプリケーションで同じタイムアウトが発生するようになりました。アプリケーションを1日以上実行し続けると、このエラーが発生します。

自分でトランザクションをコミットしたり、セッションを終了した後、操作を実行していません。 hibernate.cfg.xmlで次のプロパティを使用しています

<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://myremotehost:3306/akp</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
        <property name="hibernate.show_sql">false</property>
        <property name="hibernate.current_session_context_class">thread</property>
        <property name="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</property>

原因:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:接続が閉じられた後、操作は許可されません。接続はドライバーによって暗黙的に閉じられました。

詳細:

 Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.Connection was implicitly closed by the driver.
      at Sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at Sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.Java:39)
      at Sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.Java:27)
      at Java.lang.reflect.Constructor.newInstance(Constructor.Java:513)
      at com.mysql.jdbc.Util.handleNewInstance(Util.Java:409)
      at com.mysql.jdbc.Util.getInstance(Util.Java:384)
      at com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:1015)
      at com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:989)
      at com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:984)
      at com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:929)
      at com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException(ConnectionImpl.Java:1193)
      at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.Java:1180)
      at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.Java:4137)
      at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.Java:4103)
      at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.Java:505)
      at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.Java:423)
      at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.Java:139)
      at org.hibernate.loader.Loader.prepareQueryStatement(Loader.Java:1547)
      at org.hibernate.loader.Loader.doQuery(Loader.Java:673)
      at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.Java:236)
      at org.hibernate.loader.Loader.doList(Loader.Java:2220)
      ... 36 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 34,247,052 milliseconds ago.  The last packet sent successfully to the server was 34,247,052 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
      at Sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at Sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.Java:39)
      at Sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.Java:27)
      at Java.lang.reflect.Constructor.newInstance(Constructor.Java:513)
      at com.mysql.jdbc.Util.handleNewInstance(Util.Java:409)
      at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.Java:1118)
      at com.mysql.jdbc.MysqlIO.send(MysqlIO.Java:3321)
      at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.Java:1940)
      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 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)
      at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.Java:2104)
      at org.hibernate.loader.Loader.list(Loader.Java:2099)
      at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.Java:94)
      at org.hibernate.impl.SessionImpl.list(SessionImpl.Java:1569)
      at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.Java:283)
      at com.xyz.abc.DAO.GenericHibernateDAO.findByField(GenericHibernateDAO.Java:119)
      at com.xyz.abc.DAO.JobDAO.getJobsByLdap(JobDAO.Java:115)
      at com.xyz.abc.business.Jcr.getMyruns(Jcr.Java:272)
      at com.xyz.abc.business.abcService.getMyruns(abcService.Java:54)
      at Sun.reflect.GeneratedMethodAccessor139.invoke(Unknown Source)
      at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
      at Java.lang.reflect.Method.invoke(Method.Java:597)
      at org.Apache.axis2.rpc.receivers.RPCUtil.invokeServiceClass(RPCUtil.Java:194)
      at org.Apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.Java:102)
      at org.Apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.Java:40)
      at org.Apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.Java:114)
      at org.Apache.axis2.engine.AxisEngine.receive(AxisEngine.Java:173)
      at org.Apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.Java:173)
      at org.Apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.Java:142)
      at javax.servlet.http.HttpServlet.service(HttpServlet.Java:641)
      at javax.servlet.http.HttpServlet.service(HttpServlet.Java:722)
      at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:304)
      at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:208)
      at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:240)
      at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:203)
      at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:164)
      at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:108)
      at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:118)
      at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:379)
      at org.Apache.coyote.http11.Http11Processor.process(Http11Processor.Java:242)
      at org.Apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.Java:259)
      at org.Apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.Java:237)
      ... 4 more
Caused by: Java.net.SocketException: Software caused connection abort: socket write error

この動作を引き起こす可能性のあるアイデアはありますか?

編集:hibernate.cfg.xmlファイルで次のようになりました。正しいですか?

<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/xyz</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</property>
    <property name="hibernate.show_sql">false</property>
    <property name="hibernate.current_session_context_class">thread</property>
    <property name="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</property>
    <property name="hibernate.c3p0.min_size">5</property>
    <property name="hibernate.c3p0.max_size">20</property>
<!-- <property name="hibernate.c3p0.max_size">1800</property>-->
    <property name="hibernate.c3p0.max_statements">50</property>

    <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
    <property name="c3p0.max_statements">0</property>
    <property name="c3p0.maxIdleTimeExcessConnections">3600</property>
    <property name="c3p0.idleConnectionTestPeriod">3600</property> 
    <property name="c3p0.maxIdleTime">3600</property>
42
Akshay

@swanliuが指摘したように、それは接続不良によるものです。
ただし、サーバーのタイミングとクライアントのタイムアウトを調整する前に、まず、より適切な接続プーリング戦略を試してみます。

接続プーリング

Hibernate自体は、その接続プーリング戦略が最小限であることを認めています

ただし、Hibernate独自の接続プーリングアルゴリズムは非常に初歩的なものです。開始を支援することを目的としており、実稼働システムでの使用、またはパフォーマンステストを目的とするものではありません。最高のパフォーマンスと安定性を得るには、サードパーティのプールを使用する必要があります。 hibernate.connection.pool_sizeプロパティを接続プール固有の設定に置き換えるだけです。これにより、Hibernateの内部プールがオフになります。たとえば、c3p0を使用する場合があります。
リファレンスに記載されているとおり: http://docs.jboss.org/hibernate/core/3.3/reference/ en/html/session-configuration.html

私は個人的にC3P0。ただし、DBCPを含む他の選択肢があります。
チェックアウト

以下は、私のアプリケーションで使用されるC3P0の最小構成です。

<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="c3p0.acquire_increment">1</property> 
<property name="c3p0.idle_test_period">100</property> <!-- seconds --> 
<property name="c3p0.max_size">100</property> 
<property name="c3p0.max_statements">0</property> 
<property name="c3p0.min_size">10</property> 
<property name="c3p0.timeout">1800</property> <!-- seconds --> 

デフォルトでは、プールは接続を失効させません。 「新鮮さ」を維持するために接続の有効期限が切れる場合は、maxIdleTimeまたはmaxConnectionAgeを設定します。 maxIdleTimeは、プールからカリングされる前に、接続が未使用になる秒数を定義します。 maxConnectionAgeは、過去に設定された秒数を超えてデータベースから取得された接続をプールで強制的にカリングします。
リファレンスに記載のとおり:http://www.mchange.com/projects/c3p0/index.html# Managing_pool_size

Edit:
構成ファイルを更新しました( 参照 )。以前に自分のプロジェクトにコピーしたものをコピーしたばかりです。タイムアウトは理想的には問題を解決するはずです、それがあなたのためにうまくいかない場合は、高価な解決策があります

ファイル「c3p0.properties」を作成します。このファイルは、クラスパスのルートにある必要があります(つまり、アプリケーションの特定の部分でオーバーライドする方法はありません)。 ( 参照

# c3p0.properties
c3p0.testConnectionOnCheckout=true

この構成では、各接続は使用前にテストされます。ただし、サイトのパフォーマンスに影響する場合があります。

21

接続が長すぎる間非アクティブ(34,247,052ミリ秒≈9.5時間)であるため、MySQLはデータベース接続を暗黙的に閉じました。その後、プログラムが接続プールから不正な接続をフェッチして、MySQLNonTransientConnectionException: No operations allowed after connection closed

MySQLの提案:

接続の有効期限切れおよび/またはテストのいずれかアプリケーションで使用する前に、サーバーのクライアントタイムアウトの設定値を増やすことを検討する必要がありますまたはConnector/J接続プロパティautoReconnect=trueこの問題を回避します。

17
swanliu
  1. まず、以下に示すようにMySQL依存関係を置き換えます

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-Java</artifactId>
        <version>5.1.44</version>
    </dependency>
    
  2. 「認証プラグイン 'caching_sha2_password'」を示すエラーが表示されます。次のコマンドを実行します:

    mysql -u root -p
    ALTER USER 'username'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
    
1
Karan

接続プールを使用したくない場合(アプリに接続が1つしかないことは確かです)、これを行うことができます-接続が落ちた場合は、新しい接続を確立する必要があります-代わりにメソッド。openSession()を呼び出します。getCurrentSession()

例えば:

SessionFactory sf = null;
// get session factory
// ...
//
Session session = null;
try {
        session = sessionFactory.getCurrentSession();
} catch (HibernateException ex) {
        session = sessionFactory.openSession();
}

Mysqlを使用する場合、autoReconnectプロパティを設定できます。

    <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1/database?autoReconnect=true</property>

これがお役に立てば幸いです。

1

Mysqlに従って最新のjdbcコネクタを使用していることを確認してください。私はこの問題に直面していたので、古いjdbcコネクタを最新のものに交換すると、問題は解決しました。

最新のjdbcドライバーは https://dev.mysql.com/downloads/connector/j/ からダウンロードできます。

プラットフォーム非依存のオペレーティングシステムを選択します。 2つのオプションが表示されます。 1つはtar、もう1つはZipです。 Zipをダウンロードして展開し、jarファイルを取得して、古いコネクタに置き換えます。

これはhibernateフレームワークだけでなく、jdbcコネクタを必要とするプラットフォームで使用できます。

0
Gurbaksh Singh