@Startup
を追加することをお勧めします @Singleton
PostgreSQLデータベースへのJDBC接続を確立し、LISTEN
を使用するクラス およびNOTIFY
キャッシュの無効化を処理します。
更新 :これは、pgqと無効化のためのワーカーのコレクションを使用する別の興味深いアプローチです。
無効化シグナリング
NOTIFY
を送信する更新中のテーブルにトリガーを追加します エンティティが更新されるときはいつでも。 PostgreSQL 9.0以降では、このNOTIFY
ペイロード(通常は行ID)を含めることができるため、キャッシュ全体を無効にする必要はなく、変更されたエンティティのみを無効にする必要があります。ペイロードがサポートされていない古いバージョンでは、無効化されたエントリをタイムスタンプ付きのログテーブルに追加して、ヘルパークラスがNOTIFY
を取得したときにクエリを実行することができます。 、または単にキャッシュ全体を無効にします。
ヘルパークラスがLISTEN
になりました s NOTIFY
トリガーが送信するイベント。 NOTIFY
を取得したとき イベントの場合、個々のキャッシュエントリを無効にしたり(以下を参照)、キャッシュ全体をフラッシュしたりできます。 PgJDBCのlisten/notifyサポートを使用して、データベースからの通知をリッスンできます。 java.sql.Connection
で管理されている接続プールをアンラップする必要があります 基盤となるPostgreSQL実装にアクセスして、org.postgresql.PGConnection
にキャストできるようにします。 getNotifications()
を呼び出します その上で。
LISTEN
の代替 およびNOTIFY
、タイマーで変更ログテーブルをポーリングし、問題テーブルでトリガーを使用して、変更された行IDと変更タイムスタンプを変更ログテーブルに追加できます。このアプローチは、DBタイプごとに異なるトリガーが必要な場合を除いて移植可能ですが、非効率的でタイムリーではありません。頻繁に非効率的なポーリングが必要になりますが、それでも、listen/notifyアプローチにはない時間遅延があります。 PostgreSQLでは、UNLOGGED
を使用できます このアプローチのコストを少し削減するための表。
キャッシュレベル
EclipseLink/JPAにはいくつかのレベルのキャッシュがあります。
第1レベルのキャッシュは、EntityManager
にあります レベル。エンティティがEntityManager
に接続されている場合 persist(...)
による 、merge(...)
、find(...)
など、次にEntityManager
そのエンティティの同じインスタンスを返す必要があります 同じセッション内で再度アクセスされた場合、アプリケーションにまだ参照があるかどうかは関係ありません。データベースの内容が変更された場合、この接続されたインスタンスは最新ではありません。
オプションの第2レベルのキャッシュは、EntityManagerFactory
にあります。 レベルであり、より伝統的なキャッシュです。 2次キャッシュが有効になっているかどうかは不明です。 EclipseLinkログとpersistence.xml
を確認してください 。 EntityManagerFactory.getCache()
を使用して、第2レベルのキャッシュにアクセスできます。; Cache
を参照してください 。
@thedayofcondorは、第2レベルのキャッシュを次のようにフラッシュする方法を示しました:
em.getEntityManagerFactory().getCache().evictAll();
ただし、evict(java.lang.Class cls, java.lang.Object primaryKey)
を使用して個々のオブジェクトを削除することもできます。 電話:
em.getEntityManagerFactory().getCache().evict(theClass, thePrimaryKey);
@Startup
から使用できます @Singleton
NOTIFY
変更されたエントリのみを無効にするリスナー。
第1レベルのキャッシュは、アプリケーションロジックの一部であるため、それほど簡単ではありません。 EntityManager
がどのように機能するかを知りたいと思うでしょう 、アタッチおよびデタッチされたエンティティなどが機能します。 1つのオプションは、問題のテーブルに常にデタッチされたエンティティを使用することです。ここでは、新しいEntityManager
を使用します。 エンティティをフェッチするときはいつでも。この質問:
JPAEntityManagerセッションの無効化
エンティティマネージャのキャッシュの無効化の処理に関する有用な説明があります。ただし、EntityManager
が RESTful Webサービスは通常、短いEntityManager
を使用して実装されるため、キャッシュが問題になります。 セッション。これは、拡張永続コンテキストを使用している場合、または独自のEntityManager
を作成および管理している場合にのみ問題になる可能性があります。 コンテナ管理の永続性を使用するのではなく、セッション。