2011-07-25 20 views
6

私のプロジェクトでは、操作ごとにエンティティマネージャを閉じるのを忘れていました。しばらくすると、mysqlサーバーへの過剰な接続のために例外が発生しました。これは、各エンティティマネージャが接続を確立することを意味しますか?接続を閉じるのを忘れるとどうなりますか?私は1つのエンティティマネージャファクトリを使用しました。エンティティマネージャはデータベースへの接続を作成しますか?

答えて

9

アプリケーション管理エンティティマネージャを使用していると仮定すると、エンティティマネージャを初期化して終了する責任があります。一方、コンテナを使用してセッションBean(またはマネージクラス)にエンティティマネージャを挿入する場合、コンテナはエンティティマネージャが閉じられていることを確認する責任があります。

通常、エンティティマネージャはデータベースへの接続の作成を担当しません。代わりに、persistence.xmlで定義されている接続プールを使用します。これは、JTAエンティティマネージャとリソースローカルエンティティマネージャの両方に当てはまります。 JTAエンティティ・マネージャは、アプリケーション・サーバー環境によって提供されるJTAデータ・ソースに依存しますが、リソース・ローカル・エンティティ・マネージャは独自のプールを作成および管理します。

エンティティマネージャを閉じずに新しいインスタンスを作成する場合は、JTAデータソース(JTAエンティティマネージャ用)で接続を使い果たすか、またはサーバ定義の制限を打つことができますクライアント接続(JTAとリソースローカルエンティティマネージャの両方)各データベースインスタンスは、一定数の接続を受け入れるように構成されます。すべてのクライアントによって確立された接続の数がこの制限を超えた場合、サーバーは単に追加接続を削除します。プール(JTAエンティティマネージャ用)からの追加接続を要求するエンティティマネージャインスタンスを開くか、(リソースローカルエンティティマネージャ用の)新しいプールを作成すると、プール自体が使い果たされる可能性が非常に高くなります多くの接続が開かれていました。

接続を直接閉じることはできないし、アプリケーションから接続プールのサイズを変更することもできないため、不要になったエンティティマネージャインスタンスを閉じる必要があります。これにより、エンティティマネージャ用に確立された接続が自動的に解放されます。

また、リソース・ローカル・エンティティ・マネージャを理由で使用している場合は、すべてのエンティティ・マネージャ・インスタンスに対して適切に調整された適切なサイズの接続プールを使用することをお薦めします。 JTAエンティティマネージャを使用している場合は、コンテナに挿入されたエンティティマネージャと、適切に調整された適切なサイズの接続プールがサポートされているJTAデータソースの使用を検討してください。

3

いずれにしても、EntityManagerを明示的に開く(EMFactoryから取得する)場合は、閉じてください。接続(あなたの場合のように思われる)の有無は、JPAプロバイダに関連する設定に依存します。私たちのプロジェクトでは、EMはすべてのクエリに対して接続を開き、すぐに戻します(閉じます)。ただし、接続を維持するか、トランザクションのライフサイクルに沿って接続するかの選択肢があります。

例として、settings for OpenJPAです。私は、EMがクエリ/トランザクションの接続を開いた場合、あなたが問題に当たっていないと言います。 EMが接続して保持しているようです。

いずれにしても、作成したEMを閉じる​​必要があります。可能な場合は同じ方法で行うのがベストプラクティスです。そのため、最終的には正しいかどうかを確認し、そうすることは簡単です。

関連する問題