48

カスタムJPAマッパークラスには次のメソッドがあります。

removeUser()

1. execute 'DELETE' HQL query to remove user
2. call getEntityManager().flush();
3. call getEntityManager().clear();

clear()を正しく理解すると、すべての永続エンティティがコンテキストから削除されます。-ソース

しかし、私もここを読みました、

you should define clear architecture- and design guidelines about where a 
clear() can be called. 

clear()をいつ呼び出すかについての明確なガイドラインは何ですか?

4

3 に答える 3

57

記事はそれを説明しています。エンティティマネージャをクリアすると、関連するキャッシュが空になり、トランザクションの後半で新しいデータベースクエリが強制的に実行されます。トランザクションにバインドされたエンティティマネージャを使用する場合、エンティティマネージャをクリアする必要はほとんどありません。クリアする理由は2つあります。

  • バッチ処理を行う場合、大量のキャッシュがメモリを消費し、ダーティチェックが長くなるためにフラッシュする時間が長くなるのを防ぐため。
  • (例のように)エンティティマネージャのキャッシュを完全にバイパスするDMLまたはSQLクエリを実行している場合。この場合、キャッシュによって保持されている状態は、クエリのためにデータベースにあるものを反映していないため、この不整合を回避するためにキャッシュをクリアする必要があります。
于 2012-12-14T23:25:53.370 に答える
7

はい、それはドキュメントのポイントとしてプラットフォームのアーキテクチャスタイルに正確に依存します。

  • たとえば、アプリケーションでEMがスレッドに関連付けられている場合、トランザクション管理のソリューションの1つは、ユーザーのリクエストの開始ごとにトランザクションを開始し、リクエストの両端でキャッシュをコミットしてクリアするSession-Per-Requestパターンを実装することです。ダーティリードを防ぐため。これは単純な例です
  • 他の例はSOAプラットフォームです。各サービスについて、最初にトランザクションを開き、最後にクリアしてコミットすることもできます(同じEMが他のサービスで使用されており、ダーティリードを回避する必要がある場合)
  • 前の2つの一般的なケースを再生します。1つをバッチ処理し、すべての可能なケースでEMをバイパスします。したがって、この場合、クエリはキャッシュからではなく、DBからクエリを実行するように強制されます。
  • L1およびL2キャッシュを使用し、L1はEMによってクリアされたキャッシュであることを知っておく必要があります。膨大なデータセットを読み取る場合(そうではないはずです)(その場合、一定期間にクリアも必要になります。

ご覧のとおり、プラットフォームのケース、アーキテクチャ、スタイルによって異なります。メソッドに直接-メソッドごとにキャッシュをフラッシュしてクリアすることはお勧めできません。これはアンチパターンメソッドです。

于 2012-12-15T09:49:24.587 に答える
0

TL; DR:EntityManager.clearすでにロードされているエンティティの大部分を必要としない一連のJPA操作を実行しようとしている場合に使用します

最近、パフォーマンスの問題が発生したため、追加のログを取得する方法を尋ねられました。答えを得る前に、問題を修正する方法を見つけました。それはEntityManager.clear()です。

私がそれを使用する1つのユースケースは、集中的である可能性のある操作を分離し、エンティティマネージャーが管理するために多くのエンティティをロードすることです。私の場合、承認チェックを実行するステップがあります。トランザクションの残りの部分のほとんどのビジネスロジックでは、使用するデータのほとんど(ユーザープロファイル、低レベルのエンティティアクセスチェックなど)は必要ありません。

私が見つけたのは、それらを使用しなくても、それはセッションの残りの間残り、私の処理がすでに行われていても、最終的にはフラッシュする必要があるということでした。

フラッシュが発生する前に実行するclearと、エンティティマネージャーからそれらが解放され、管理されなくなります。

于 2021-12-30T03:53:46.567 に答える