EclipseLinkキャッシュは、クラスと主キーの値に基づいて最近読み取られたり書き込まれたオブジェクトが格納される、インメモリー・リポジトリです。キャッシュによって、最近読み取られたり書き込まれたオブジェクトを保持してメモリー内でアクセスすることで、データベース・アクセスを最小限に抑え、ロック・レベルと分離レベルを制御し、オブジェクト・アイデンティティを管理してパフォーマンスを向上できます。
EclipseLinkには、次のエンティティ・キャッシング注釈が定義されています。
@Cache
@TimeOfDay
@ExistenceChecking
EclipseLinkには、EclipseLinkキャッシュを構成するために指定できる多くの永続性ユニット・プロパティも用意されています。これらのプロパティによって、注釈を補完したり、注釈のかわりを提供できます。これらの注釈およびプロパティの詳細は、『Oracle Fusion Middleware Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』を参照してください。
この章の内容は次のとおりです。
EclipseLinkは、2つのタイプのキャッシュを使用します(共有型の永続性ユニット・キャッシュ(L2)は、データ・ソースから取得されたオブジェクトまたはそれに書き込まれたオブジェクトを保持し、独立型の永続性コンテキスト・キャッシュ(L1)は、トランザクションに参加中のオブジェクトを保持します)。永続性コンテキスト(エンティティ・マネージャ)が正常にデータ・ソースにコミットされると、EclipseLinkではそれに応じて永続性ユニット・キャッシュが更新されます。概念的には、永続性コンテキスト・キャッシュはEntityManager
によって表され、永続性ユニット・キャッシュはEntityManagerFactory
によって表されます。
内部的に、EclipseLinkは、永続性ユニット・キャッシュをEclipseLinkセッションに、永続性コンテキスト・キャッシュをEclipseLink作業ユニットに格納します。図9-1に示すとおり、永続性ユニット・キャッシュ(セッション・キャッシュ)と永続性コンテキスト・キャッシュ(作業ユニット・キャッシュ)は、データ・ソース接続と連携して、EclipseLinkアプリケーションのオブジェクトを管理します。オブジェクトのライフ・サイクルは、この3つのメカニズムに依存しています。
永続性ユニット・キャッシュは、特定の永続性ユニットに接続されたクライアントにサービスを提供する共有キャッシュ(L2)です。EntityManager
オブジェクトを使用してデータ・ソースを対象にブジェクトの読取りまたは書込みを行うと、EclipseLinkは、オブジェクトのコピーを永続性ユニットのキャッシュに保存し、同じ永続性ユニットにアクセスする他のすべてのプロセスがそれらにアクセスできるようにします。
EclipseLinkは、次から永続性ユニット・キャッシュにオブジェクトを追加します。
データ・ストア: EclipseLinkが読取り操作を実行した場合
永続性コンテキスト・キャッシュ: 永続性コンテキストが正常にトランザクションをコミットした場合
EclipseLinkでは、独立、共有、保護という3つのキャッシュ分離レベルが定義されています。これらのレベルの詳細は、9.1.3項「共有、独立、保護、弱参照および読取り専用キャッシュ」を参照してください。
一意の永続性ユニット名ごとに、個別の永続性ユニット・キャッシュがあります。このキャッシュは概念的にはEntityManagerFactory
を使用して格納されますが、同じ永続性ユニット名を持つ2つのファクトリは、同じキャッシュを共有し、効果的に同じ永続性ユニット・インスタンスになります。同じ永続性ユニットがJava EEの2つの個別のアプリケーションにデプロイされても、それらの永続性ユニットの完全名は、通常、一意のままであるため、個別のキャッシュが使用されます。データ・ソース、データベースURL、ユーザー、テナントIDなどの特定の永続性ユニット・プロパティは、永続性ユニットの一意名に影響を与えることがあり、結果として個別の永続性ユニット・インスタンスと個別のキャッシュが使用されます。eclipselink.session.name
永続性ユニット・プロパティを使用して、2つの永続性ユニットを強制的に同じインスタンスに解決し、キャッシュを共有できます。
永続性コンテキスト・キャッシュは、EntityManager内で操作を提供する独立キャッシュ(L1)です。これは、永続性ユニット・キャッシュのオブジェクトを管理して分離し、永続性コンテキストがデータ・ソースに変更をコミットした後に、変更済または新規のオブジェクトを永続性ユニット・キャッシュに書き込みます。
注意: コミット済の変更のみが共有永続性ユニット・キャッシュにマージされ、フラッシュなどの操作は、トランザクションがコミットされるまで永続性ユニット・キャッシュに影響しません。 |
永続性コンテキスト・キャッシュのライフ・サイクルは、アプリケーション管理とコンテナ管理の永続性コンテキスト間で異なります。作業ユニット・キャッシュは、作業ユニット内の操作にサービスを提供します。作業ユニット・キャッシュは、オブジェクトを保持してセッション・キャッシュから分離し、作業ユニットが変更内容をデータ・ソースにコミットした後、変更されたオブジェクトまたは新規オブジェクトをセッション・キャッシュに書き込みます。
アプリケーション管理の永続性コンテキストは、EntityManagerFactory
からのアプリケーションによって作成されます。アプリケーション管理の永続性コンテキストのキャッシュは、EntityManager
がクローズされるか、clear()
がコールされるまで変更されません。この場合、アプリケーション管理の永続性ユニットの存続期間を短く維持するか、clear()
を使用して永続性コンテキスト・キャッシュが大きくなりすぎないように、または永続性ユニット・キャッシュおよびデータベースとの同期を失わないようにすることが重要です。通常、トランザクションまたはリクエストごとに個別のEntityManager
を作成する必要があります。
拡張永続性コンテキストは、それがコンテナによって管理されていても、アプリケーション管理の永続性コンテキストと同じキャッシュ動作になります。
EclipseLinkでは、存続期間の長い永続性コンテキスト(2層アプリケーションなど)用にWEAK
参照モード・オプションもサポートされます。9.1.3.4項「弱参照モード」を参照してください。
コンテナ管理の永続性コンテキストは、通常、SessionBean
か、Java EEコンテナまたはフレームワーク(Springなど)によって管理される他のオブジェクトにインジェクションされます。コンテナ管理の永続性コンテキストのキャッシュは、トランザクションの継続期間中のみ維持されます。トランザクションで読み取られたエンティティは、トランザクションの完了後にデタッチされ、後続のトランザクションでの編集のためにマージされる必要があります。
注意: EclipseLinkでは、永続性コンテキストがクローズされた後に、エンティティのLAZYリレーションシップにアクセスすることが可能です。 |
EclipseLinkでは、3つのキャッシュ分離レベルが定義されています。キャッシュ分離レベルでは、永続性ユニットおよび永続性コンテキストによってエンティティのキャッシュを実行する方法が定義されます。キャッシュ分離レベルは次のとおりです。
独立: エンティティは、永続性ユニットではなく、永続性コンテキストにのみキャッシュされます。9.1.3.1項「独立キャッシュ」を参照してください。
共有: エンティティは、永続性コンテキストと永続性ユニットの両方にキャッシュされ、読取り専用エンティティは共有されて永続性ユニットにのみキャッシュされます。9.1.3.2項「共有キャッシュ」を参照してください。
保護: エンティティは、永続性コンテキストと永続性ユニットの両方にキャッシュされ、読取り専用エンティティは分離されて永続性ユニットと永続性コンテキストにキャッシュされます。9.1.3.3項「保護キャッシュ」を参照してください。
独立キャッシュ(L1)は、永続性コンテキストに格納されるキャッシュです。これは、トランザクションまたはユーザー・セッション・ベースのキャッシュです。エンティティでキャッシュ分離をISOLATED
に設定すると、その共有キャッシュが無効になります。独立キャッシュでは、オブジェクトが永続性コンテキストに読み取られてリフレッシュが使用されない場合を除き、すべての問合せおよび検索操作はデータベースにアクセスします。
独立キャッシュを使用して次の操作を実行できます。
共有キャッシュで高揮発性データのキャッシュを回避します。
シリアライズ可能トランザクションの分離を実現します。
各永続性コンテキストは、初期状態で空の独立キャッシュを所有します。永続性コンテキストの独立キャッシュは、永続性コンテキストがクローズされるか、EntityManager.clear()
操作が使用されると破棄されます。
EntityManager
を使用して独立エンティティを読み取ると、EntityManager
によって、データベースから直接エンティティが読み取られ、永続性コンテキストの独立キャッシュに格納されます。読取り専用エンティティを読み取っても、それは独立キャッシュに格納されたままですが、変更追跡は行われません。
永続性コンテキストは、接続プールまたは排他接続を使用してデータベースにアクセスできます。永続性ユニット・プロパティのeclipselink.jdbc.exclusive-connection.mode
を使用して、排他接続を使用できます。排他接続を使用すると、ユーザーごとの読取りおよび書込みのセキュリティが強化されます。特定の問合せを構成して、永続性コンテキストの排他接続を使用することもできます。
注意:
|
共有キャッシュ(L2)は、永続性ユニットに格納されるキャッシュです。これは、永続性ユニット全体に対応する共有オブジェクト・キャッシュです。エンティティでキャッシュ分離をSHARED
に設定すると、その共有キャッシュが有効になります。共有キャッシュでは、リフレッシュが使用される場合を除き、問合せおよび検索操作は共有キャッシュに対して解決されます。
共有キャッシュを使用して次の操作を実行できます。
IDまたは索引でエンティティを検索または問い合せるときに、データベース・アクセスを回避することでパフォーマンスを向上します。
エンティティのリレーションシップにアクセスするときに、データベース・アクセスを回避することでパフォーマンスを向上します。
読取り専用エンティティの永続性コンテキスト全体でオブジェクト・アイデンティティを維持します。
EntityManager
を使用して共有エンティティを検索すると、最初にEntityManager
によって永続性ユニットの共有キャッシュが確認されます。エンティティは、永続性ユニットの共有キャッシュに存在しない場合、データベースから読み取られて永続性ユニットの共有キャッシュに格納され、コピーも永続性コンテキストの独立キャッシュに格納されます。IDや索引付き属性を基準としない問合せは、すべて最初にデータベースにアクセスします。問合せの各結果行について、オブジェクトがすでに共有キャッシュに存在する場合、共有オブジェクト(とそのリレーションシップ)が使用され、それ以外の場合、新しいオブジェクトが行から作成されて共有キャッシュに配置され、コピーが独立キャッシュに配置されます。独立コピーは、読取り専用が使用されないかぎり常に返されます。読取り専用の場合、独立コピーは必要ないため、共有オブジェクトが返されます。
共有キャッシュのサイズおよびメモリー使用量は、エンティティのキャッシュ・タイプに応じて異なります。JPA Cache
およびEclipseLink JpaCache
注釈を使用して、キャッシュを無効化またはクリアすることもできます。
保護キャッシュ・オプションでは、共有オブジェクトで独立オブジェクトを参照できます。エンティティでキャッシュ分離をPROTECTED
に設定すると、その共有キャッシュが有効になります。保護オプションは、共有オプションとほぼ同じですが、保護エンティティは共有とは異なり、独立エンティティに対するリレーションシップを持つことができます。
保護キャッシュを使用して次の操作を実行できます。
IDまたは索引でエンティティを検索または問い合せるときに、データベース・アクセスを回避することでパフォーマンスを向上します。
共有エンティティに対するエンティティのリレーションシップにアクセスするときに、データベース・アクセスを回避することでパフォーマンスを向上します。
読取り専用エンティティの永続性コンテキストに対する独立を保証します。
独立エンティティに対するリレーションシップを可能にします。
保護エンティティは、共有エンティティと同じライフ・サイクルを持ちます(リレーションシップと読取り専用を除く)。保護エンティティの共有エンティティに対するリレーションシップは、共有キャッシュにキャッシュされますが、独立エンティティに対するリレーションシップは隔離され、共有キャッシュにキャッシュされません。@Noncacheable
注釈を使用して、共有エンティティに対するリレーションシップのキャッシュを無効化することもできます。読取り専用の保護エンティティは、常に独立キャッシュにコピーされますが、変更追跡は行われません。
EclipseLinkでは、存続期間の長い永続性コンテキストに対して専用の永続性コンテキスト・キャッシュが提供されます。通常、永続性コンテキストの存続期間は短く維持するのが最適です(リクエストごと、またはトランザクションごとに新しいEntityManager
を作成するなど)。これは、ステートレス・モデルと呼ばれます。これによって、永続性コンテキストが大きくなりすぎ、メモリーやパフォーマンスの問題が発生することを防ぎます。また、永続性コンテキストにキャッシュされたオブジェクトが失効したり、コミット済の状態との同期を失わないようにします。
一部の2層アプリケーションまたはステートフル・モデルでは、存続期間の長い永続性コンテキストが必要です。EclipseLinkでは、これらのタイプのアプリケーションに対して特殊な弱参照モードのオプションが提供されます。弱参照モードでは、永続性コンテキストのオブジェクトに対して弱い参照が維持されます。これによって、アプリケーションによる参照がない場合に、オブジェクトのガベージ・コレクションを行うことができます。これによって、永続性コンテキストが大きくなりすぎることを防ぎ、メモリー使用量を削減してパフォーマンスを向上します。新規、削除済または変更済のオブジェクトは、すべてコミットが発生するまで強い参照を使用して保持されます。
弱参照モードは、eclipselink.persistence-context.reference-mode
永続性ユニット・プロパティを通じて構成できます。次のオプションを使用できます。
HARD
: これはデフォルトで、弱参照は使用されません。永続性コンテキストは、クリアまたはクローズされるまで増大します。
WEAK
: 弱参照が使用されます。参照されていない未変更オブジェクトは、ガベージ・コレクションの対象になります。遅延変更追跡を使用しているオブジェクトは、ガベージ・コレクションの対象になりません。
FORCE_WEAK
: 弱参照が使用されます。参照されていない未変更オブジェクトは、ガベージ・コレクションの対象になります。遅延変更追跡を使用している変更済の(ただし参照されていない)オブジェクトも、ガベージ・コレクションの対象になり、すべての変更が失われます。
エンティティは、@ReadOnly
注釈またはread-only
XML属性を使用して読取り専用として構成できます。読取り専用エンティティは、変更を追跡されず、更新はすべて無視されます。読取り専用エンティティは、永続化または削除できません。読取り専用エンティティは、変更が禁止されていますが、EclipseLinkでは現在これが強制されません。読取り専用オブジェクトを変更すると、永続性ユニット・キャッシュが破損する可能性があります。
eclipselink.read-only
問合せヒントを使用して、読取り専用オブジェクトを返すように問合せを構成することもできます。
読取り専用のSHARED
エンティティでは、問合せから共有インスタンスが返されます。すべての永続性コンテキストのすべての問合せから、同じエンティティが返されます。共有読取り専用エンティティは、永続性コンテキストにコピーまたは隔離されません。これによって、オブジェクトのコピーおよびオブジェクトの変更追跡のコストを回避することで、パフォーマンスを向上できます。この場合、メモリーが削減され、ヒープ使用量が減少し、パフォーマンスが向上します。オブジェクト・アイデンティティも読取り専用エンティティの永続性ユニット全体で維持され、アプリケーションではこれらの共有オブジェクトに対する参照を保持できます。
読取り専用のISOLATED
またはPROTECTED
エンティティは、永続性コンテキストから返された独立コピーを保持しています。これによって、オブジェクトの変更追跡が回避され、パフォーマンスとメモリー使用量が多少改善しますが、SHARED
エンティティほどではありません。
EclipseLinkには、異なるメモリー要件を持つ複数の異なるキャッシュ・タイプがあります。キャッシュのサイズ(キャッシュされたオブジェクトの数)も構成可能です。使用するキャッシュのタイプおよびサイズは、アプリケーション、失効データの可能性、JVMおよびマシンで使用可能なメモリー量、ガベージ・コレクションのコスト、およびデータベースのデータ量によって異なります。
デフォルトでは、EclipseLinkは、100個のオブジェクトの初期サイズでSOFT_CACHE
を使用します。キャッシュ・サイズは固定されませんが、初期サイズは固定で、EclipseLinkはメモリーのオブジェクトがガベージ・コレクションの対象になるまで、キャッシュからオブジェクトを排除しません。CACHE
タイプが使用されるとオブジェクトは排除されますが、これは推奨されません。また、SOFT_CACHE
およびHARD_CACHE
のキャッシュ・サイズは、メモリーに保持するオブジェクトの最小数を決定できるソフトまたはハード・サブキャッシュのサイズです。
オブジェクト・アイデンティティをクラス単位でどのように管理するかを構成することができます。ClassDescriptor
オブジェクトでは、表9-1で説明するキャッシュおよびアイデンティティ・マップのオプションが使用できます。
表9-1 キャッシュおよびアイデンティティ・マップのオプション
オプション(キャッシュ・タイプ) | キャッシング | アイデンティティの保証 | メモリー使用量 |
---|---|---|---|
|
はい |
はい |
非常に多い |
|
はい |
はい |
少ない |
|
はい |
はい |
多い |
SOFT_CACHEおよびHARD_CACHEキャッシュ・タイプ |
はい |
はい |
中程度 |
他にNONE
およびCACHE
という2つのオプションがあります。これらのオプションはお薦めしません。
このオプションでは、完全なキャッシュとアイデンティティの保証を行います。オブジェクトは、実際に削除されるまでメモリーからフラッシュされません。
すべてのオブジェクトがキャッシュされ、キャッシュから削除されることはありません。キャッシュ・サイズは、最大サイズに達すると2倍まで許容されます。この方法を使用すると、多くのオブジェクトが読み取られる場合、メモリーの負荷が高くなることがあります。このオプションはバッチ操作には使用しないでください。
このアイデンティティ・マップは、データ・セットのサイズが小さく、メモリーの容量が大きい場合に使用することをお薦めします。
このオプションでは、ガベージ・コレクションが行われていないオブジェクトのみがキャッシュされます。アプリケーションによって参照されているオブジェクトは、キャッシュされます。
WEAKキャッシュ・タイプでは、使用するメモリーが完全アイデンティティ・マップより少ないかわりに、クライアント/サーバー・トランザクション全体にわたる永続キャッシュ方法も使用しません。オブジェクトは、サーバー側(つまり、サーバーJVM内)でアプリケーションによって参照されなくなると、ガベージ・コレクションの対象になります。
このオプションは、WEAKキャッシュ・タイプとほぼ同じですが、キャッシュで弱参照のかわりにソフト参照を使用するところが異なります。アプリケーションによって参照されているオブジェクトはキャッシュされ、オブジェクトがキャッシュから削除されるのは、メモリーが少ない場合のみです。
ソフト・アイデンティティ・マップではオブジェクトのキャッシュを最適化でき、メモリー残量が少ない場合はJVMでオブジェクトのガベージ・コレクションを行うことも可能です。
これらのオプションは、弱いキャッシュとほぼ同じですが、最も使用頻度の高いサブキャッシュが維持されるところが異なります。サブキャッシュでは、ソフトまたはハード参照を使用して、これらのオブジェクトがガベージ・コレクションの対象とならないように、またはメモリー上でJVMが少ない場合にのみガベージ・コレクションの対象となるようにします。
ソフト・キャッシュとハード・キャッシュでは、より効率的にメモリーを使用できます。これらのマップでは、ガベージ・コレクションされたオブジェクトを解放します(最近使用された一定数のオブジェクトは除く)。弱参照でキャッシュされたオブジェクトは、トランザクションが複数のクライアント/サーバー起動にわたって使用される場合、フラッシュされる可能性があることに注意してください。サブキャッシュのサイズは、サイズ・オプションで指定されたキャッシュのサイズに比例します。キャッシュ・サイズは、トランザクションで保持するオブジェクトの数に設定する必要があります。
このキャッシュは、キャッシュで使用されるメモリーを制御する手段として、ほとんどの場合に使用をお薦めします。
NONE
およびCACHE
オプションでは、オブジェクト・アイデンティティが維持されないため、これらは非常に限定的な状況でのみ使用する必要があります。NONE
ではどのオブジェクトもキャッシュされません。CACHE
では、LRU
方式で一定数のオブジェクトのみがキャッシュされます。これらのキャッシュ・タイプは、オブジェクトに対するリレーションシップが存在しない場合にのみ使用する必要があります。これらのオプションの使用はお薦めしません。キャッシュを無効にするには、かわりにキャッシュ分離をISOLATED
に設定してください。
キャッシュ・タイプの構成時には、次のガイドラインに従ってください。
存続期間の長いオブジェクトでは、SOFT
、SOFT_CACHE
またはHARD_CACHE
キャッシュ・タイプを使用します。どのような場合にどちらを選択するかについては、9.2.6.1項「WEAK、SOFTおよびHARDキャッシュ・タイプの内部について」を参照してください。
存続期間の短いオブジェクトでは、WEAK
キャッシュ・タイプを使用します。
インスタンスがほとんど存在しない存続期間の長いオブジェクト(参照データなど)では、FULL
キャッシュ・タイプを使用します。
注意:
|
キャッシュが不要であるか、使用しない場合、キャッシュ分離をISOLATED
に設定して共有キャッシュを無効にします。
注意:
|
9.2.6.1項「WEAK、SOFTおよびHARDキャッシュ・タイプの内部について」を参照してください。
WEAK
およびSOFT
キャッシュ・タイプでは、JVM弱参照およびソフト参照を使用して、アプリケーションによって参照されるオブジェクトがキャッシュ内に保持されるようにします。アプリケーションでオブジェクト参照を解除すると、JVMでは自由にオブジェクトのガベージ・コレクションを実行します。弱参照またはソフト参照がガベージ・コレクションされる時期は、JVMによって決定されます。一般的に、弱参照は、それぞれのJVMガベージ・コレクション操作でガベージ・コレクションされると想定されます。
SOFT_CACHE
およびHARD_CACHE
キャッシュ・タイプには、次の2つのキャッシュが含まれます。
参照キャッシュ: それぞれソフトまたはハード参照を含めたLinkedList
として実装されるキャッシュ
弱キャッシュ: 弱参照を含めたMap
として実装されるキャッシュ
指定したサイズでSOFT_CACHE
またはHARD_CACHE
キャッシュを作成すると、参照キャッシュのLinkedList
は正確にそのサイズになります。弱キャッシュのMap
のサイズは、その初期サイズと同じです(指定したサイズより多くのオブジェクトが読み取られると、弱キャッシュは増大します)。EclipseLinkはガベージ・コレクションを制御しないため、弱く保持されたオブジェクトは適切なときにJVMが削除します。
参照キャッシュはLinkedList
として実装されるため、リストの最後に新しいオブジェクトが追加されます。そのため、これは本質的に最低使用頻度(LRU)キャッシュです(固定サイズで、最大サイズに到達するとリストの先頭のオブジェクトが削除されます)。
SOFT_CACHE
およびHARD_CACHE
は、基本的に同じタイプのキャッシュです。HARD_CACHE
は、一部のJVMでの問題を回避するために構成されました。
アプリケーションを実行しているシステムでメモリー不足の状態が頻繁に発生する場合や、プラットフォームのJVMで弱い参照とソフト参照が同様に扱われる場合には、参照キャッシュ内のオブジェクトのガベージ・コレクションが頻繁に行われるため、参照キャッシュによるパフォーマンス向上の利点は得られません。この場合、HARD_CACHE
の使用をお薦めします。これはSOFT_CACHE
と同じですが、参照キャッシュでハード参照を使用する点が異なります。そうすることで、アプリケーションは参照キャッシュによるパフォーマンス向上の利点を確実に得ることができます。
HARD_CACHE
またはSOFT_CACHE
内のオブジェクトは、参照キャッシュから削除されると、弱キャッシュに格納されます。このオブジェクトは引き続きキャッシュされていますが、JVMは弱参照をガベージ・コレクションすることを随時決定できるため、どれくらいの間キャッシュに保持されるかはEclipseLinkでは保証できません。
共有セッション・キャッシュに対して実行される問合せは、インメモリー問合せと呼ばれます。インメモリー問合せを慎重に構成することで、パフォーマンスを向上できます。
デフォルトでは、主キーに基づいてシングル・オブジェクトを検索する問合せは、必要なオブジェクトをまずキャッシュから取得し、オブジェクトがキャッシュに存在しない場合にのみ、データ・ソースで検索を行います。その他すべての問合せタイプの場合は、デフォルトでデータベースを最初に検索します。特定の問合せを、メモリー内キャッシュ、データベース、その両方のうち、いずれに対して実行するかを指定できます。
失効したデータは、データ・ソースにコミットされた最新バージョンでないオブジェクトをキャッシュした結果として発生します。失効したデータの発生を防止するには、適切なキャッシュ・ロック方法を実装します。
EclipseLinkでは、デフォルトで、読取りまたは書込み操作中のキャッシュ・ロックを最小限に抑えるために同時実行性が最適化されます。非常に明確な理由があって変更する場合を除き、EclipseLinkの分離レベルはデフォルトのまま使用してください。EclipseLinkでの分離レベルの詳細は、9.1.3項「共有、独立、保護、弱参照および読取り専用キャッシュ」を参照してください。
キャッシュ・ロックにより、プロセスがオブジェクトを読み取る、または書き込むタイミングを制御します。キャッシュ・ロックの構成に応じて、別のプロセス内で使用されているオブジェクトの読取りまたは書込みが可能かどうかが決まります。
キャッシュを適切に管理すると、アプリケーションの効率が高まります。キャッシュはデータベース・アクセスを減少させ、オブジェクト・アイデンティティの管理の重要な部分を占めるため、キャッシュを完全にオフにすることはほとんどありません。
キャッシュを最大限に活用し、失効したデータがアプリケーションに使用されることを最小限に抑えるために、次のことをお薦めします。
ロック・ポリシーを構成しておくことで、変更中のオブジェクトの値が変更されるのを防止するか、または少なくとも変更された時間を識別することができます。これは通常、オプティミスティック・ロックを使用して行います。EclipseLinkでは、数値バージョン・フィールド、タイムスタンプ・バージョン・フィールド、一部のフィールド、すべてのフィールドなど、複数のロック・ポリシーでロックできます。オプティミスティック・ロックとペシミスティック・ロックについては、次の項で説明します。
EclipseLinkオプティミスティック・ロックの使用をお薦めします。オプティミスティック・ロックを使用した場合、すべてのユーザーにデータへの読取りアクセス権限があります。ユーザーが変更を書き込もうとすると、アプリケーションにより、ユーザーがデータを読み取ってから、そのデータが変更されていないかが確認されます。
バージョン・ロック・ポリシーまたはフィールド・ロック・ポリシーを使用できます。バージョン・ロック・ポリシーの使用をお薦めします。詳細は、6.2.4.1項「オプティミスティック・バージョン・ロック・ポリシー」および6.2.4.1.3項「オプティミスティック・フィールド・ロック・ポリシー」を参照してください。
ペシミスティック・ロックを使用した場合は、データを更新する目的でそのデータにアクセスする最初のユーザーが、更新を完了するまでデータをロックします。このアプローチの短所は、並行性が損われること、デッドロックになる可能性があることです。
問合せレベルでペシミスティック・ロックのサポートを使用することを検討してください。6.2.4.2項「ペシミスティック・ロック・ポリシー」を参照してください。
特定のクラスで使用するデータを他のアプリケーションが変更できる場合、そのクラスには弱いスタイルのキャッシュを使用します。たとえば、SoftCacheWeakIdentityMap
またはWeakIdentityMap
を指定すると、参照対象として削除されたオブジェクトをキャッシュが保持する期間は最も短くなります。
すべての問合せには、選択したオブジェクトの最新バージョンをデータ・ソースで検索し、その情報でキャッシュを更新することをEclipseLinkに強制するフラグを含めることができます。
ディスクリプタAPIを使用して、オブジェクトを無効として指定できます(問合せによって無効なオブジェクトの読取りが試行されると、EclipseLinkはそのオブジェクトの最新バージョンを取得するためにデータ・ソースにアクセスし、その情報でキャッシュを更新します)。手動でオブジェクトを無効として指定するか、オブジェクトを無効として指定する条件を制御するためにCacheInvalidationPolicy
を使用することができます。詳細は、9.6項「キャッシュの期限切れと無効化について」を参照してください。
アプリケーションが読取り中心で、変更がすべて、複数の分散セッションで実行されている同一Javaアプリケーションによって行われる場合は、EclipseLinkのキャッシュ・コーディネーション機能の使用が有効なことがあります。これは、データの失効は防止しませんが、できるかぎり最小限に抑えます。詳細は、9.11項「キャッシュ・コーディネーションについて」を参照してください。
分散システムの中には、システム内のサーバー全体で少数のオブジェクトのみが一貫していればよいものがあります。逆に、いくつかの特定のオブジェクトが、負荷に関係なく、常に最新の状態であることを求めるシステムもあります。そのようなシステムを構築する場合は、分散キャッシュ・コーディネーションを行うほどの負荷をかけずに、データベースから選択したオブジェクトを適切な間隔で明示的にリフレッシュすることができます。
このタイプの方法を実装するには、次の手順を実行します。
必要なオブジェクトをリフレッシュする一連の問合せを構成します。
適切なリフレッシュ・ポリシーを設定します。
必要に応じて問合せを起動し、オブジェクトをリフレッシュします。
問合せを実行すると、必要なオブジェクトがキャッシュ内に存在する場合、EclipseLinkは、より新しいバージョンがないかどうかデータベースをチェックすることなく、キャッシュされたオブジェクトをが返します。これにより、EclipseLinkがデータベースの結果から作成する必要のあるオブジェクトの数が減るため、この方法はコーディネートされていないキャッシュ環境に最適です。ただし、コーディネートされたキャッシュ環境では必ずしも最善の方法ではありません。
この動作をオーバーライドするには、データベースのオブジェクトがキャッシュ内のオブジェクトよりも常に優先されることを示すリフレッシュ・ポリシーを設定します。この場合、キャッシュされたオブジェクトがデータベースのデータで更新されます。
このタイプのリフレッシュ・ポリシーは、アプリケーションの特性に応じて、EclipseLinkの各ディスクリプタに実装することも、特定の問合せのみに実装することもできます。
デフォルトでは、オブジェクトは、明示的に削除されるか、ガベージ・コレクションの対象になるまで共有キャッシュ内に存在し続けます。
expiry
を使用すると、エンティティ・インスタンスをキャッシュで失効させるまでのミリ秒数や、エンティティ・クラスのすべてのインスタンスをキャッシュで失効させる時刻を指定してエンティティを構成できます。有効期限は、@Cache
注釈または<cache>
XML要素で設定し、次の2つの方法で構成できます。
expiry
: エンティティ・インスタンスを失効させるまでの秒数。
expiryTimeOfDay
: エンティティ・クラスのすべてのインスタンスをキャッシュで失効させる24時間制の時刻を表す@TimeOfDay
。
インスタンスが失効すると、単にキャッシュ内で無効化されます。キャッシュからは削除されませんが、次にアクセスされると、アクセスに使用された問合せの一部として、データベースからリフレッシュされます。
アプリケーションでは、JPA Cache
APIまたはEclipseLink JpaCache
APIを使用して、キャッシュ内のオブジェクトを明示的に無効化することもできます。
有効期限は、問合せ結果キャッシュでも使用できます。9.8項「問合せ結果キャッシュについて」を参照してください。
無効化は、キャッシュ・コーディネーションを通じてクラスタ内で、またはデータベース・イベント通知を使用するデータベース・イベントでも使用できます。9.11.4項「コーディネートされたキャッシュおよびクラスタリング」を参照してください。
別の方法として、注釈またはXMLでキャッシュ・オブジェクトが無効になる状況を指定できるCacheInvalidationPolicy
を使用して、任意のオブジェクトを構成できます。問合せによって無効なオブジェクトの読取りが試行されると、EclipseLinkはそのオブジェクトの最新バージョンを取得するためにデータ・ソースにアクセスし、その情報でキャッシュを更新します。
使用可能なCacheInvalidationPolicy
インスタンスの詳細は、『Oracle Fusion Middleware Oracle TopLinkソリューション・ガイド』のキャッシュ有効期限の設定に関する項を参照してください。
キャッシュの無効化ポリシーは次のレベルで構成できます。
すべてのオブジェクトに適用されるプロジェクト・レベル
オブジェクトごとにプロジェクト・レベルの構成をオーバーライドするディスクリプタ・レベル
問合せによって返される結果に適用される問合せレベル
結果を独自の内部キャッシュにキャッシュするように問合せを構成すると、問合せレベルで構成するキャッシュの無効化ポリシーは、セッション・キャッシュに適用されるのと同様の方法で、問合せの内部キャッシュに適用されます。
コーディネート・キャッシュを使用している場合は、オブジェクトに無効フラグが設定されていることをEclipseLinkが伝える方法をカスタマイズできます。9.11項「キャッシュ・コーディネーションについて」を参照してください。
EclipseLinkのCacheInvalidationPolicy
APIでは、注釈やXMLを通じて使用できない拡張機能をいくつか提供しています。独自のCacheInvalidationPolicy
を定義して、独自の有効期限または無効化ポリシーを定義することも可能です。DescriptorCustomizer
の使用を通じて拡張構成を行い、エンティティのClassDescriptor
をカスタマイズできます。
CacheInvalidationPolicy
の拡張オプションは次のとおりです。
isInvalidationRandomized
: これによって、無効化時間を10%ランダム化し、多数のインスタンスが同時に無効になってデータベース負荷のボトルネックにならないようにします。これはデフォルトでは使用されません。
shouldRefreshInvalidObjectsOnClone
: これによって、別のオブジェクトからのリレーションシップを通じてアクセスされる無効なオブジェクトが、永続性コンテキストで確実にリフレッシュされます。このオプションは、デフォルトでは有効になっています。
shouldUpdateReadTimeOnUpdate
: これによって、オブジェクトが正常に更新されるときに、オブジェクトの読取り時間が更新されます。これはデフォルトでは無効です。
EclipseLinkキャッシュは、エンティティIDで索引付けされます。これによって、ID別のfind()
操作、リレーションシップおよび問合せが可能になり、キャッシュ・ヒットを取得してデータベース・アクセスを回避できます。キャッシュは、非ID問合せではデフォルトで使用されません。すべての非ID問合せは、データベースにアクセスし、結果セットで返される行ごとにキャッシュによって解決されます。
アプリケーションは、そのID以外に他の一意キーを各モデルに持つことが多くあります。生成されたIDが使用される場合、これはごく普通です。アプリケーションは、頻繁にこれらの一意キーに基づいて問合せを行うため、これらの問合せ時のデータベース・アクセスを回避するため、キャッシュ・ヒットを取得できる方が便利です。
キャッシュ索引では、EclipseLinkキャッシュ内にインメモリー索引を作成することで、非IDフィールドでキャッシュ・ヒットが可能になります。キャッシュ索引は、単一のフィールドまたはフィールドのセットに配置できます。索引付けされたフィールドは、更新可能です(通常は一意となりますが、これは要件ではありません)。索引付けされたフィールドを含む問合せでは、キャッシュ・ヒットを取得できます。索引付けされた問合せから取得できるのは、単一の結果のみです。
キャッシュ索引は、@CacheIndex
および@CacheIndexes
注釈と、<cache-index>
XML要素を使用して構成できます。@CacheIndex
は、エンティティに定義するか、属性に定義して属性に索引付けすることができます。エンティティに定義する索引では、索引に使用するcolumnNames
を定義する必要があります。索引は、オブジェクトが更新可能な属性を使用して更新されたときに、再度索引付けするように構成できます。
問合せ結果キャッシュを使用して、索引付けされていない問合せの問合せ結果をキャッシュすることも可能です。詳細は、9.8項「問合せ結果キャッシュについて」を参照してください。
EclipseLinkの問合せ結果キャッシュでは、オブジェクトがキャッシュされる場合と同じように、名前付き問合せの結果をキャッシュできます。
EclipseLinkのデフォルトでは、IDまたはキャッシュの索引付けされたフィールドを使用する場合を除き、すべての問合せでデータベースにアクセスします。結果の行はキャッシュで解決され、オブジェクトがキャッシュされている場合、リレーションシップに対する追加の問合せは回避されますが、元の問合せは常にデータベースにアクセスします。EclipseLinkには、キャッシュを問い合せるオプションがありますが、EclipseLinkではデータベースのすべてのオブジェクトがキャッシュ内に存在するとは想定されないため、これらのオプションはデフォルトでは使用されません。問合せ結果キャッシュでは、索引付けされていない結果リスト問合せでもキャッシュから利点を得ることができます。
問合せ結果キャッシュは、問合せの名前と問合せのパラメータで索引付けされます。結果をキャッシュできるのは名前付き問合せのみで、動的問合せでは問合せ結果キャッシュを使用できません。同様に、ヒントやプロパティを設定するなど、実行前に名前付き問合せを変更すると、キャッシュされた結果を使用できません。
問合せ結果キャッシュでは、オブジェクト・キャッシュのように、アプリケーションからコミット済の変更が選択されません。これは、読取り専用オブジェクトをキャッシュする場合にのみ使用する必要があります(または、失効した結果のキャッシュを回避するために無効化ポリシーを使用する必要があります)。結果セットのオブジェクトに対するコミット済の変更は、選択されますが、結果セットに影響する変更(結果セットから追加または削除する必要のある新規または変更済オブジェクトなど)は選択されません。
問合せ結果キャッシュでは、固定サイズ、キャッシュ・タイプおよび無効化オプションがサポートされます。
EclipseLinkでは、デフォルトで、読取りまたは書込み操作中のキャッシュ・ロックを最小限に抑えるために同時実行性が最適化されます。非常に明確な理由があって変更する場合を除き、EclipseLinkのトランザクション分離構成はデフォルトのまま使用してください。
EclipseLinkキャッシュをクラスごとにチューニングすると、分散キャッシュ・コーディネーションが不要になります。この設定のチューニングは、キャッシュ・コーディネーションを実装する前に必ず行ってください。詳細は、『Oracle Fusion Middleware Oracle TopLinkソリューション・ガイド』のTopLink対応アプリケーションの監視および最適化に関する項を参照してください。
すべてのアプリケーションのデータを最新の状態に維持する必要性は、分散アプリケーションを構築する際の設計上の大きな課題です。環境内のサーバー数が増加するにつれて、この課題の難しさも増していきます。EclipseLinkには、分散アプリケーションのデータを最新の状態に維持する、分散キャッシュ・コーディネーション機能が用意されています。
キャッシュ・コーディネーションにより、分散アーキテクチャで発生するオプティミスティック・ロック例外の数は減少し、アプリケーションで失敗するトランザクションや繰り返されるトランザクションの数も減少します。とはいえ、キャッシュ・コーディネーションを行っても、効果的なロック・ポリシーが不要になることはありません。最新データが効率的に使用できるように、キャッシュ・コーディネーションはオプティミスティックまたはペシミスティック・ロックとともに使用する必要があります。キャッシュ・コーディネーションは、オプティミスティック・ロック・ポリシーとともに使用することをお薦めします。
キャッシュの無効化を使用すると、キャッシュ・コーディネーションが高速になります。詳細は、9.6項「キャッシュの期限切れと無効化について」を参照してください。
図9-2に示すように、キャッシュ・コーディネーションは、セッションの複数のインスタンス(大部分の場合、分散されている)が相互にオブジェクト変更をブロードキャストできるようにするセッション機能であり、これにより、各セッションのキャッシュは、最新の状態に保たれるか、次回読み取るデータ・ソースを基にオブジェクトを更新する必要があることを通知されます。
注意: 独立クライアント・セッションは、キャッシュ・コーディネーションと組み合せて使用することはできません。詳細は、9.1.3項「共有、独立、保護、弱参照および読取り専用キャッシュ」を参照してください。 |
セッションが分散されている場合、つまり、アプリケーションに複数のセッションが含まれている場合(同一JVM内、複数JVM内、あるいは複数サーバー上)、セッションをホスティングしているサーバーがネットワーク上で相互接続されているかぎり、セッションはキャッシュ・コーディネーションに参加できます。検出サービスを必要とするタイプのコーディネート・キャッシュでは、サーバーでユーザー・データグラム・プロトコル(UDP)通信およびマルチキャスト構成がサポートされることも必要です。詳細は、9.11.2項「コーディネートされたキャッシュのアーキテクチャとタイプ」を参照してください。
この項の内容は次のとおりです。
キャッシュ・コーディネーションにより、パフォーマンスが向上し、次の特性を持つアプリケーションに対して失効データが発生する可能性が低下します。
変更はすべて、複数の分散セッションで実行されている同一Javaアプリケーションにより実行されます。
読取り中心です。
同一オブジェクトを定期的にリクエストおよび更新します。
これらの特性を持たないアプリケーションでは、パフォーマンスを最大化するため、キャッシュ・コーディネーションを使用しないでください。
失効データの発生頻度を削減する他のオプションについては、9.4項「失効したデータの処理について」を参照してください。
変更がブロードキャストされるようにキャッシュ・コーディネーションを構成する際、次の通信プロトコルのいずれかを使用できます。
JMSコーディネート・キャッシュ(Java Message Service (JMS)用)
RMIコーディネート・キャッシュ(Remote Method Invocation (RMI)用)
JMSコーディネート・キャッシュの場合は、特定のセッションのコーディネート・キャッシュが起動されると、そのセッションは、自身のJNDIネーミング・サービス情報を使用してJMSサーバーへの接続を検索および作成します。すべての参加セッションが同一JMSサーバー上の同一トピックに接続されると、コーディネート・キャッシュが準備完了状態になります。この時点で、セッションはオブジェクト変更メッセージの送受信を開始できます。この後、同一JMSおよびJNDIネーミング・サービス情報を使用して、同一コーディネート・キャッシュに参加しているすべてのセッションを構成できます。
例9-1は、JMSコーディネート・キャッシュ用に構成されたpersistence.xml
ファイルを示します。
例9-1 JMSキャッシュ・コーディネーション用のpersistence.xmlファイル
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_2_0.xsd" version="2.0"> <persistence-unit name="acme" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="eclipselink.cache.coordination.protocol" value="jms"/> <property name="eclipselink.cache.coordination.jms.topic" value="jms/ACMETopic"/> <property name="eclipselink.cache.coordination.jms.factory" value="jms/ACMETopicConnectionFactory"/> </properties> </persistence-unit> </persistence>
JMSの構成の詳細は、『Oracle Fusion Middleware Oracle TopLinkソリューション・ガイド』の永続性プロパティを使用したJMSキャッシュ・コーディネーションの構成に関する項を参照してください。JMSプロバイダのドキュメントも参照してください。
RMIコーディネート・キャッシュでは、特定のセッションのコーディネート・キャッシュが起動すると、セッションによってネーミング・サービスの接続がバインドされ(RMIレジストリまたはJNDI)、独自のネーミング・サービス情報を含む通知メッセージが作成され、その通知がマルチキャスト・グループにブロードキャストされます。同じマルチキャスト・グループに属するセッションでこの通知が受信されると、通知メッセージのネーミング・サービス情報が使用され、新しく通知されたセッションのコーディネート・キャッシュとの双方向接続が確立されます。この方法ですべての参加セッションが相互接続されると、コーディネート・キャッシュの準備が完了し、その時点でセッションはオブジェクト変更メッセージの送受信を開始できます。その後、セッションがデプロイされているホストを識別するネーミング情報を使用して各セッションを構成できます。
例9-2は、RMIコーディネート・キャッシュ用に構成されたpersistence.xml
ファイルを示します。
例9-2 RMIキャッシュ・コーディネーション用のpersistence.xmlファイル
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_2_0.xsd" version="2.0"> <persistence-unit name="acme" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="eclipselink.cache.coordination.protocol" value="rmi"/> </properties> </persistence-unit> </persistence>
詳細は、『Oracle Fusion Middleware Oracle TopLinkソリューション・ガイド』の永続性プロパティを使用したRMIキャッシュ・コーディネーションの構成に関する項を参照してください。
org.eclipse.persistence.sessions.coordination
パッケージのクラスを使用すると、カスタム・ソリューション用の独自のコーディネート・キャッシュを定義できます。
アプリケーション・クラスタは、単一のアプリケーションまたはアプリケーション・セットへのリクエストに対応する中間層サーバー・マシンまたはVMのセットです。複数のサーバーを使用して、アプリケーションのスケーラビリティの向上、またはフォルト・トレランスと高可用性の提供(あるいはその両方)を行います。通常は、同じアプリケーションがクラスタ内のすべてのサーバーにデプロイされ、アプリケーション・リクエストはサーバーのセット全体でロード・バランシングされます。アプリケーション・クラスタは、単一のデータベースまたはデータベース・クラスタにアクセスします。アプリケーション・クラスタでは、新しいサーバーを追加してスケーラビリティを向上したり、更新やサービス提供などのためにサーバーを削除できます。
アプリケーション・クラスタは、Java EEサーバー、WebコンテナまたはJavaサーバー・アプリケーションで構成されます。
EclipseLinkは、任意のクラスタ環境で動作できます。クラスタ環境での主な問題は、共有永続性ユニット(L2)・キャッシュの使用です。共有キャッシュ(EclipseLinkプロジェクトではデフォルトで有効)を使用している場合、各サーバーは独自のキャッシュを維持し、各キャッシュ・データは他のサーバーおよびデータベースとの同期を失うことがあります。
EclipseLinkでは、サーバー・キャッシュの同期を保証するために、クラスタ環境でキャッシュ・コーディネーションが提供されます。
クラスタ環境でのキャッシュについては、次のように他の多くの解決策があります。
共有キャッシュを無効化します(@Cacheable(false)
または@Cache(isolation=ISOLATED
)の設定を使用)。
読取り専用オブジェクトのみをキャッシュします。
失効したデータを減らすためにキャッシュ無効化タイムアウトを設定します。
フレッシュ・データが必要な場合にオブジェクトまたは問合せに対してリフレッシュを使用します。
書込み整合性を保証するためにオプティミスティック・ロックを使用します(失効したデータに対する書込みは失敗し、キャッシュは自動的に無効化されます)。
分散キャッシュを使用します(TopLink GridによるTopLinkとOracle Coherenceの統合など)。
データベース・イベントを使用して、キャッシュ内の変更データを無効化します(EclipseLinkによるOracle Query Change Notificationのサポートなど)。
キャッシュ・コーディネーションによって、クラスタ内の異なるサーバー(または同じサーバー)にデプロイされた永続性ユニットのセットで変更を同期できます。キャッシュ・コーディネーションは、クラスタ内の各サーバーの永続性ユニットごとに動作し、トランザクション・オブジェクトの変更通知をクラスタ内の他の永続性ユニットにブロードキャストできます。EclipseLinkでは、RMIおよびJMSを介したキャッシュ・コーディネーションがサポートされます。キャッシュ・コーディネーション・フレームワークは、拡張可能なため、他のオプションを開発することもできます。
キャッシュ・コーディネーションは、各トランザクションの変更をクラスタ内の他のサーバーにブロードキャストすることで動作します。他のサーバーは、それぞれ変更通知を受信し、キャッシュ内の変更済オブジェクトを無効化するか、キャッシュ済オブジェクトの状態を変更によって更新します。キャッシュ・コーディネーションは、データベースのコミット後に発生するため、コミット済の変更のみがブロードキャストされます。
キャッシュ・コーディネーションは、アプリケーションが失効データを取得する可能性を大幅に低減しますが、その可能性が排除されることはありません。オプティミスティック・ロックは、引き続きデータの整合性を保証するために使用する必要があります。単一のサーバー・アプリケーションでも、ペシミスティック・ロックが使用される場合を除き、失効データは永続性コンテキスト内で発生する可能性があります。オプティミスティック(またはペシミスティック)・ロックは、任意のマルチユーザー・システムでデータの整合性を保証するために常に必要です。
TopLinkには、キャッシュ用に次の永続性プロパティの拡張機能が含まれます。これらの拡張機能の詳細は、『Oracle Fusion Middleware Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』を参照してください。
cache.coordination.channel
cache.coordination.jms.factory
cache.coordination.jms.host
cache.coordination.jms.reuse-topic-publisher
cache.coordination.jms.topic
cache.coordination.jndi.initial-context-factory
cache.coordination.jndi.password
cache.coordination.jndi.user
cache.coordination.naming-service
cache.coordination.propagate-asynchronously
cache.coordination.protocol
cache.coordination.remove-connection-on-error
cache.coordination.rmi.announcement-delay
cache.coordination.rmi.multicast-group
cache.coordination.rmi.multicast-group.port
cache.coordination.rmi.packet-time-to-live
cache.coordination.rmi.url
cache.coordination.thread.pool.size
RMIとJMSのキャッシュ・コーディネーションは、両方ともOracle WebLogicで動作します。WebLogicクラスタが使用される場合、JNDIがクラスタ・サーバー間でレプリケートされるため、cache.coordination.rmi.url
またはcache.coordination.jms.host
オプションは不要です。JMSのキャッシュ・コーディネーションでは、JMSトピックは(Oracle WebLogic 10.3.6以上の)サーバーの1つにのみデプロイする必要があります。JMSメッセージの通信量が多い場合、状況に応じて専用のJMSサーバーを用意することをお薦めします。
WebLogicで他のJMSサービスを使用する場合、他の要件が存在することがあります。
JMSのキャッシュ・コーディネーションは、Glassfishで動作します。Glassfishクラスタが使用される場合、JNDIがクラスタ・サーバー間でレプリケートされるため、cache.coordination.jms.host
オプションは不要です。
Glassfishで他のJMSサービスを使用する場合、他の要件が存在することがあります。
RMIのキャッシュ・コーディネーションは、JNDIネーミング・サービス・オプションがGlassfishクラスタで使用されている場合には動作しません。RMIは、eclipselink.cache.coordination.naming-service
オプションがrmi
に設定されている場合に動作します。各サーバーでは、サーバーごとに異なるpersistence.xml
ファイルを用意するか、サーバーのシステム・プロパティとしてURLを設定するか、カスタマイザを使用して独自のeclipselink.cache.coordination.rmi.url
オプションを提供する必要があります。
JMSのキャッシュ・コーディネーションでは、IBM WebSphere上で問題が発生することがあります。JMSへのアクセスを可能にするため、メッセージドリブンBean (MDB)の使用が必要になることがあります。MDBをキャッシュ・コーディネーションとともに使用するには、eclipselink.cache.coordination.protocol
オプションの値をjms-publishing
に設定します。アプリケーションでも、そのEARファイルのキャッシュ・コーディネーション・メッセージを処理するMDBをデプロイする必要があります。
例9-3に、MDBを構成するために必要なJavaコードを示します。
例9-3 キャッシュ・コーディネーションのメッセージドリブンBean
@MessageDriven public class JMSCacheCoordinationMDB implements MessageListener { private JMSTopicRemoteConnection connection; @PersistenceUnit(unitName="acme") private EntityManagerFactory emf; public void ejbCreate() { this.connection = new JMSTopicRemoteConnection(this.emf.unwrap(ServerSession.class).getCommandManager()); } public void onMessage(Message message) { this.connection.onMessage(message); } }