1

JPA/Hibernateを介したクエリとストレートSQLが機能しているように見える読み取り専用操作のために、まだトランザクションを開始していないコードがあるようです。hibernate/jpa セッションはフレームワークによって開かれていましたが、レガシー コードのいくつかの場所で、トランザクションが開かれていないことがわかりました。

結局、EntityManager.persist と EntityManager.merge を使用しない限り、コードは通常実行されるようです。ただし、たまに (おそらく 1/10) 回、サーブレット コンテナーがこのエラーで失敗します...

Failed to load resource: the server responded with a status of 500 (org.hibernate.exception.JDBCConnectionException: The last packet successfully received from the server was 314,024,057 milliseconds ago.  The last packet sent successfully to the server was 314,024,057 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.) 

私が知る限り、この問題は、クエリが行われる前にトランザクションが開始されていない、アプリケーション コードのわずかな箇所で発生します。この動作を引き起こすのは、実行中の非トランザクションクエリである可能性があると考えている人はいますか?

参考までに、ここに私たちのスタックがあります...

-Guice -Guice-Persist -Guice-Servlet -MySql 5.1.63 -Hibernate/C3P0 4.1.4.Final -Jetty

4

1 に答える 1

0

はい、そう思います。

トランザクションを開かずにクエリを開始すると、このトランザクションは下層のレイヤーによって自動的に開かれます。開かれたトランザクションを含むこの接続は、接続プールに返され、別のユーザーに渡されます。別のユーザーは、既に開かれているトランザクションへの接続を受け取り、不整合な状態になる可能性があります。

ここ私の会社では、過去に読み取り専用の非トランザクション クエリで多くの問題があり、これを処理するためにフレームワークを調整しました。それに加えて、BoneCP 開発者と話をしたところ、プールに返されたコミットされていないトランザクションの自動ロールバックや、トランザクションのコミットを忘れたメソッドのスタック トレースの出力など、この問題の処理に役立つ一連の機能の開発を受け入れてくれました。

この問題はここで議論されました: http://jolbox.com/forum/viewtopic.php?f=3&t=98

于 2013-04-17T21:03:15.120 に答える