ヘッダーをスキップ
Oracle® Fusion Middleware Oracle TopLinkの理解
12c (12.1.3)
E56235-01
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

8 キャッシュの理解

この章では、キャッシュについて紹介および説明します。EclipseLinkキャッシュは、クラスと主キーの値に基づいて最近読み取られたり書き込まれたオブジェクトが格納される、インメモリー・リポジトリです。キャッシュによって、最近読み取られたり書き込まれたオブジェクトを保持してメモリー内でアクセスすることで、データベース・アクセスを最小限に抑え、ロック・レベルと分離レベルを制御し、オブジェクト・アイデンティティを管理してパフォーマンスを向上できます。

EclipseLinkにより定義されているエンティティ・キャッシュ注釈は、『Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』のキャッシュ注釈に関する項に記載されています。

EclipseLinkには、EclipseLinkキャッシュを構成するために指定できる多くの永続性ユニット・プロパティも用意されています。これらのプロパティによって、注釈を補完したり、注釈のかわりを提供できます。これらのプロパティのリストについては、『Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』のキャッシュに関する項を参照してください。

この章の内容は次のとおりです。

8.1 キャッシュ・アーキテクチャについて

EclipseLinkは、2つのタイプのキャッシュを使用します(共有型の永続性ユニット・キャッシュ(L2)は、データ・ソースから取得されたオブジェクトまたはそれに書き込まれたオブジェクトを保持し、独立型の永続性コンテキスト・キャッシュ(L1)は、トランザクションに参加中のオブジェクトを保持します)。永続性コンテキスト(エンティティ・マネージャ)が正常にデータ・ソースにコミットされると、EclipseLinkではそれに応じて永続性ユニット・キャッシュが更新されます。概念的には、永続性コンテキスト・キャッシュはEntityManagerによって表され、永続性ユニット・キャッシュはEntityManagerFactoryによって表されます。

内部的に、EclipseLinkは、永続性ユニット・キャッシュをEclipseLinkセッションに、永続性コンテキスト・キャッシュをEclipseLink永続性ユニットに格納します。図8-1に示すとおり、永続性ユニット(セッション)と永続性コンテキスト(作業ユニット)は、データ・ソース接続と連携して、EclipseLinkアプリケーションのオブジェクトを管理します。

データベースからの読取りリクエストは、EclipseLinkセッションの永続性ユニット(セッション)・キャッシュに送信されます。データベースからの書込みリクエストは、EclipseLinkの永続性コンテキスト(作業ユニット)・キャッシュに送信されます。永続性(セッション)・キャッシュにより、オブジェクトが永続性コンテキストに登録されます。コミットまたはマージ・トランザクション中に、永続性コンテキスト・キャッシュにより永続性ユニット・キャッシュがリフレッシュされます。オブジェクトのライフ・サイクルは、これらのメカニズムに依存しています。

図8-1 オブジェクトのライフ・サイクルとEclipseLinkのキャッシュ

図8-1の説明が続きます
「図8-1 オブジェクトのライフ・サイクルとEclipseLinkのキャッシュ」の説明

8.1.1 永続性ユニット・キャッシュ

永続性ユニット・キャッシュは、特定の永続性ユニットに接続されたクライアントにサービスを提供する共有キャッシュ(L2)です。EntityManagerオブジェクトを使用してデータ・ソースを対象にブジェクトの読取りまたは書込みを行うと、EclipseLinkは、オブジェクトのコピーを永続性ユニットのキャッシュに保存し、同じ永続性ユニットにアクセスする他のすべてのプロセスがそれらにアクセスできるようにします。

EclipseLinkは、次から永続性ユニット・キャッシュにオブジェクトを追加します。

  • データ・ストア: EclipseLinkが読取り操作を実行した場合

  • 永続性コンテキスト・キャッシュ: 永続性コンテキストが正常にトランザクションをコミットした場合

EclipseLinkでは、独立、共有、保護という3つのキャッシュ分離レベルが定義されています。これらのレベルの詳細は、8.1.3項「共有、独立、保護、弱参照および読取り専用キャッシュ」を参照してください。

一意の永続性ユニット名ごとに、個別の永続性ユニット・キャッシュがあります。このキャッシュは概念的にはEntityManagerFactoryを使用して格納されますが、同じ永続性ユニット名を持つ2つのファクトリは、同じキャッシュを共有し、効果的に同じ永続性ユニット・インスタンスになります。同じ永続性ユニットがJava EEの2つの個別のアプリケーションにデプロイされても、それらの永続性ユニットの完全名は、通常、一意のままであるため、個別のキャッシュが使用されます。データ・ソース、データベースURL、ユーザー、テナントIDなどの特定の永続性ユニット・プロパティは、永続性ユニットの一意名に影響を与えることがあり、結果として個別の永続性ユニット・インスタンスと個別のキャッシュが使用されます。eclipselink.session.name永続性ユニット・プロパティを使用して、2つの永続性ユニットを強制的に同じインスタンスに解決し、キャッシュを共有できます。

8.1.2 永続性コンテキスト・キャッシュ

永続性コンテキスト・キャッシュは、EntityManager内で操作を提供する独立キャッシュ(L1)です。これは、永続性ユニット・キャッシュのオブジェクトを管理して分離し、永続性コンテキストがデータ・ソースに変更をコミットした後に、変更済または新規のオブジェクトを永続性ユニット・キャッシュに書き込みます。


注意:

コミット済の変更のみが共有永続性ユニット・キャッシュにマージされ、フラッシュなどの操作は、トランザクションがコミットされるまで永続性ユニット・キャッシュに影響しません。


永続性コンテキスト・キャッシュのライフ・サイクルは、アプリケーション管理とコンテナ管理の永続性コンテキスト間で異なります。永続性コンテキスト(作業ユニット)・キャッシュは、永続性ユニット内の操作にサービスを提供します。これは、永続性コンテキスト(セッション)・キャッシュのオブジェクトを管理して分離し、永続性ユニットがデータ・ソースに変更をコミットした後に、変更済または新規のオブジェクトを永続性コンテキスト・キャッシュに書き込みます。

8.1.2.1 アプリケーション管理の永続性コンテキスト

アプリケーション管理の永続性コンテキストは、EntityManagerFactoryからのアプリケーションによって作成されます。アプリケーション管理の永続性コンテキストのキャッシュは、EntityManagerがクローズされるか、clear()がコールされるまで変更されません。この場合、アプリケーション管理の永続性ユニットの存続期間を短く維持するか、clear()を使用して永続性コンテキスト・キャッシュが大きくなりすぎないように、または永続性ユニット・キャッシュおよびデータベースとの同期を失わないようにすることが重要です。通常、トランザクションまたはリクエストごとに個別のEntityManagerを作成する必要があります。

拡張永続性コンテキストは、それがコンテナによって管理されていても、アプリケーション管理の永続性コンテキストと同じキャッシュ動作になります。

EclipseLinkでは、存続期間の長い永続性コンテキスト(2層アプリケーションなど)用にWEAK参照モード・オプションもサポートされます。8.1.3.4項「弱参照モード」を参照してください。

8.1.2.2 コンテナ管理の永続性コンテキスト

コンテナ管理の永続性コンテキストは、通常、SessionBeanか、Java EEコンテナまたはフレームワーク(Springなど)によって管理される他のオブジェクトにインジェクションされます。コンテナ管理の永続性コンテキストのキャッシュは、トランザクションの継続期間中のみ維持されます。トランザクションで読み取られたエンティティは、トランザクションの完了後にデタッチされ、後続のトランザクションでマージまたは編集する必要があります。


注意:

EclipseLinkでは、永続性コンテキストがクローズされた後に、エンティティのLAZYリレーションシップにアクセスすることが可能です。


8.1.3 共有、独立、保護、弱参照および読取り専用キャッシュ

EclipseLinkでは、3つのキャッシュ分離レベルが定義されています。キャッシュ分離レベルでは、永続性ユニットおよび永続性コンテキストによってエンティティのキャッシュを実行する方法が定義されます。キャッシュ分離レベルは@Cache注釈のisolation属性で設定できます。分離属性に使用できる値は次のとおりです。

  • isolated: エンティティは、永続性ユニットではなく、永続性コンテキストにのみキャッシュされます。8.1.3.1項「独立キャッシュ」を参照してください。

  • shared: エンティティは、永続性コンテキストと永続性ユニットの両方にキャッシュされ、読取り専用エンティティは共有されて永続性ユニットにのみキャッシュされます。8.1.3.2項「共有キャッシュ」を参照してください。

  • protected: エンティティは、永続性コンテキストと永続性ユニットの両方にキャッシュされ、読取り専用エンティティは分離されて永続性ユニットおよび永続性コンテキストにキャッシュされます。8.1.3.3項「保護キャッシュ」を参照してください。

8.1.3.1 独立キャッシュ

独立キャッシュ(L1)は、永続性コンテキストに格納されるキャッシュです。これは、トランザクションまたはユーザー・セッション・ベースのキャッシュです。エンティティでキャッシュ分離をisolatedに設定すると、その共有キャッシュが無効になります。独立キャッシュでは、オブジェクトが永続性コンテキストに読み取られてリフレッシュが使用されない場合を除き、すべての問合せおよび検索操作はデータベースにアクセスします。

独立キャッシュを使用して次の操作を実行できます。

  • 共有キャッシュで高揮発性データのキャッシュを回避します。

  • シリアライズ可能トランザクションの分離を実現します。

各永続性コンテキストは、初期状態で空の独立キャッシュを所有します。永続性コンテキストの独立キャッシュは、永続性コンテキストがクローズされるか、EntityManager.clear()操作が使用されると破棄されます。

EntityManagerを使用して独立エンティティを読み取ると、EntityManagerによって、データベースから直接エンティティが読み取られ、永続性コンテキストの独立キャッシュに格納されます。読取り専用エンティティを読み取っても、それは独立キャッシュに格納されたままですが、変更追跡は行われません。

永続性コンテキストは、接続プールまたは排他接続を使用してデータベースにアクセスできます。永続性ユニット・プロパティのeclipselink.jdbc.exclusive-connection.modeを使用して、排他接続を使用できます。排他接続を使用すると、ユーザーごとの読取りおよび書込みのセキュリティが強化されます。特定の問合せを構成して、永続性コンテキストの排他接続を使用することもできます。


注意:

EntityManagerに排他接続が含まれる場合、その使用が終了したらEntityManagerをクローズする必要があります。EntityManagerのガベージ・コレクションが行われるときに、ファイナライザに依存して接続を解放することはお薦めしません。管理永続性コンテキストを使用する場合、これをクローズする必要はありません。


8.1.3.2 共有キャッシュ

共有キャッシュ(L2)は、永続性ユニットに格納されるキャッシュです。これは、永続性ユニット全体に対応する共有オブジェクト・キャッシュです。エンティティでキャッシュ分離をsharedに設定すると、その共有キャッシュが有効になります。共有キャッシュでは、リフレッシュが使用される場合を除き、問合せおよび検索操作は共有キャッシュに対して解決されます。

共有キャッシュを使用して次の操作を実行できます。

  • IDまたは索引でエンティティを検索または問い合せるときに、データベース・アクセスを回避することでパフォーマンスを向上します。

  • エンティティのリレーションシップにアクセスするときに、データベース・アクセスを回避することでパフォーマンスを向上します。

  • 読取り専用エンティティの永続性コンテキスト全体でオブジェクト・アイデンティティを維持します。

EntityManagerを使用して共有エンティティを検索すると、最初にEntityManagerによって永続性ユニットの共有キャッシュが確認されます。エンティティは、永続性ユニットの共有キャッシュに存在しない場合、データベースから読み取られて永続性ユニットの共有キャッシュに格納され、コピーも永続性コンテキストの独立キャッシュに格納されます。IDや索引付き属性を基準としない問合せは、すべて最初にデータベースにアクセスします。問合せの各結果行について、オブジェクトがすでに共有キャッシュに存在する場合、共有オブジェクト(とそのリレーションシップ)が使用され、それ以外の場合、新しいオブジェクトが行から作成されて共有キャッシュに配置され、コピーが独立キャッシュに配置されます。独立コピーは、読取り専用が使用されないかぎり常に返されます。読取り専用の場合、独立コピーは必要ないため、共有オブジェクトが返されます。

共有キャッシュのサイズおよびメモリー使用量は、エンティティのキャッシュ・タイプにより異なります。@Cache注釈の属性は、キャッシュの無効化およびクリアに使用することもできます。

8.1.3.3 保護キャッシュ

保護キャッシュ・オプションでは、共有オブジェクトで独立オブジェクトを参照できます。エンティティでキャッシュ分離をprotectedに設定すると、その共有キャッシュが有効になります。保護オプションは、共有オプションとほぼ同じですが、保護エンティティは共有とは異なり、独立エンティティに対するリレーションシップを持つことができます。

保護キャッシュを使用して次の操作を実行できます。

  • IDまたは索引でエンティティを検索または問い合せるときに、データベース・アクセスを回避することでパフォーマンスを向上します。

  • 共有エンティティに対するエンティティのリレーションシップにアクセスするときに、データベース・アクセスを回避することでパフォーマンスを向上します。

  • 読取り専用エンティティの永続性コンテキストに対する独立を保証します。

  • 独立エンティティに対するリレーションシップを可能にします。

保護エンティティは、共有エンティティと同じライフ・サイクルを持ちます(リレーションシップと読取り専用を除く)。保護エンティティの共有エンティティに対するリレーションシップは、共有キャッシュにキャッシュされますが、独立エンティティに対するリレーションシップは隔離され、共有キャッシュにキャッシュされません。@Noncacheable注釈を使用して、共有エンティティに対するリレーションシップのキャッシュを無効化することもできます。読取り専用の保護エンティティは、常に独立キャッシュにコピーされますが、変更追跡は行われません。

8.1.3.4 弱参照モード

EclipseLinkでは、存続期間の長い永続性コンテキストに対して専用の永続性コンテキスト・キャッシュが提供されます。通常、永続性コンテキストの存続期間は短く維持するのが最適です(リクエストごと、またはトランザクションごとに新しいEntityManagerを作成するなど)。これは、ステートレス・モデルと呼ばれます。これによって、永続性コンテキストが大きくなりすぎ、メモリーやパフォーマンスの問題が発生することを防ぎます。また、永続性コンテキストにキャッシュされたオブジェクトが失効したり、コミット済の状態との同期を失わないようにします。

一部の2層アプリケーションまたはステートフル・モデルでは、存続期間の長い永続性コンテキストが必要です。EclipseLinkでは、これらのタイプのアプリケーションに対して特殊な弱参照モードのオプションが提供されます。弱参照モードでは、永続性コンテキストのオブジェクトに対して弱い参照が維持されます。これによって、アプリケーションによる参照がない場合に、オブジェクトのガベージ・コレクションを行うことができます。これによって、永続性コンテキストが大きくなりすぎることを防ぎ、メモリー使用量を削減してパフォーマンスを向上します。新規、削除済または変更済のオブジェクトは、すべてコミットが発生するまで強い参照を使用して保持されます。

弱参照モードは、eclipselink.persistence-context.reference-mode永続性ユニット・プロパティを通じて構成できます。次のオプションを使用できます。

  • HARD: これはデフォルトで、弱参照は使用されません。永続性コンテキストは、クリアまたはクローズされるまで増大します。

  • WEAK: 弱参照が使用されます。参照されていない未変更オブジェクトは、ガベージ・コレクションの対象になります。遅延変更追跡を使用しているオブジェクトは、ガベージ・コレクションの対象になりません。

  • FORCE_WEAK: 弱参照が使用されます。参照されていない未変更オブジェクトは、ガベージ・コレクションの対象になります。遅延変更追跡を使用している変更済の(ただし参照されていない)オブジェクトも、ガベージ・コレクションの対象になり、すべての変更が失われます。

8.1.3.5 読取り専用エンティティ

エンティティは、@ReadOnly注釈またはread-only XML属性を使用して読取り専用として構成できます。読取り専用エンティティは、変更を追跡されず、更新はすべて無視されます。読取り専用エンティティは、永続化または削除できません。読取り専用エンティティは、変更が禁止されていますが、EclipseLinkでは現在これが強制されません。読取り専用オブジェクトを変更すると、永続性ユニット・キャッシュが破損する可能性があります。

eclipselink.read-only問合せヒントを使用して、読取り専用オブジェクトを返すように問合せを構成することもできます。

読取り専用のsharedエンティティでは、問合せから共有インスタンスが返されます。すべての永続性コンテキストのすべての問合せから、同じエンティティが返されます。共有読取り専用エンティティは、永続性コンテキストにコピーまたは隔離されません。これによって、オブジェクトのコピーおよびオブジェクトの変更追跡のコストを回避することで、パフォーマンスを向上できます。この場合、メモリーが削減され、ヒープ使用量が減少し、パフォーマンスが向上します。オブジェクト・アイデンティティも読取り専用エンティティの永続性ユニット全体で維持され、アプリケーションではこれらの共有オブジェクトに対する参照を保持できます。

読取り専用のisolatedまたはprotectedエンティティは、永続性コンテキストから返された独立コピーを保持しています。これによって、オブジェクトの変更追跡が行われなくなるため、パフォーマンスとメモリー使用量が多少改善しますが、sharedエンティティほどではありません。

8.2 キャッシュのタイプとサイズについて

EclipseLinkには、異なるメモリー要件を持つ複数の異なるキャッシュ・タイプがあります。キャッシュのサイズ(キャッシュされたオブジェクトの数)も構成可能です。使用するキャッシュのタイプおよびサイズは、アプリケーション、失効データの可能性、JVMおよびマシンで使用可能なメモリー量、ガベージ・コレクションのコスト、およびデータベースのデータ量によって異なります。

共有オブジェクト・キャッシュのキャッシュ・タイプおよびサイズは、@Cache注釈のtypeおよびsize属性で構成することができます。また、問合せ結果キャッシュのキャッシュ・タイプは、eclipselink.query-results-cache.type永続性ユニット・プロパティで構成することができます。詳細は、『Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』@Cache注釈およびeclipselink.query-results-cache.type永続性ユニット・プロパティに関する説明を参照してください。

デフォルトでは、EclipseLinkは、100個のオブジェクトの初期サイズでSOFT_WEAKを使用します。キャッシュ・サイズは固定されませんが、初期サイズは固定で、EclipseLinkはメモリーのオブジェクトがガベージ・コレクションの対象になるまで、キャッシュからオブジェクトを排除しません。CACHEタイプが使用されるとオブジェクトは排除されますが、これは推奨されません。また、SOFT_WEAKおよびHARD_WEAKのキャッシュ・サイズは、メモリーに保持するオブジェクトの最小数を決定できるソフトまたはハード・サブキャッシュのサイズです。

オブジェクト・アイデンティティをクラス単位でどのように管理するかを構成することができます。ClassDescriptorオブジェクトでは、表8-1で説明するキャッシュおよびアイデンティティ・マップのオプションが使用できます。

表8-1 キャッシュおよびアイデンティティ・マップのオプション

オプション キャッシング アイデンティティの保証 メモリー使用量

FULLキャッシュ・タイプ


はい

はい

非常に多い

WEAKキャッシュ・タイプ


はい

はい

少ない

SOFTキャッシュ・タイプ


はい

はい

多い

SOFT_WEAKおよびHARD_WEAKキャッシュ・タイプ


はい

はい

中程度


他にNONEおよびCACHEという2つのオプションがあります。これらのオプションはお薦めしません。

type属性の値はeclipselink.cache.type.<ENTITY>およびeclipselink.cache.type.default永続性ユニット・プロパティでオーバーライドできます。

8.2.1 FULLキャッシュ・タイプ

このオプションでは、完全なキャッシュとアイデンティティの保証を行います。オブジェクトは、実際に削除されるまでメモリーからフラッシュされません。

すべてのオブジェクトがキャッシュされ、キャッシュから削除されることはありません。キャッシュ・サイズは、最大サイズに達すると2倍まで許容されます。この方法を使用すると、多くのオブジェクトが読み取られる場合、メモリーの負荷が高くなることがあります。このオプションはバッチ操作には使用しないでください。

このアイデンティティ・マップは、データ・セットのサイズが小さく、メモリーの容量が大きい場合に使用することをお薦めします。

8.2.2 WEAKキャッシュ・タイプ

このオプションでは、ガベージ・コレクションが行われていないオブジェクトのみがキャッシュされます。アプリケーションによって参照されているオブジェクトは、キャッシュされます。

WEAKキャッシュ・タイプでは、使用するメモリーが完全アイデンティティ・マップより少ないかわりに、クライアント/サーバー・トランザクション全体にわたる永続キャッシュ戦略も使用しません。オブジェクトは、サーバー側(つまり、サーバーJVM内)でアプリケーションによって参照されなくなると、ガベージ・コレクションの対象になります。

8.2.3 SOFTキャッシュ・タイプ

このオプションは、WEAKキャッシュ・タイプとほぼ同じですが、キャッシュで弱参照のかわりにソフト参照を使用するところが異なります。アプリケーションによって参照されているオブジェクトはキャッシュされ、オブジェクトがキャッシュから削除されるのは、メモリーが少ない場合のみです。

ソフト・アイデンティティ・マップではオブジェクトのキャッシュを最適化でき、メモリー残量が少ない場合はJVMでオブジェクトのガベージ・コレクションを行うことも可能です。

8.2.4 SOFT_WEAKおよびHARD_WEAKキャッシュ・タイプ

これらのオプションは、弱いキャッシュとほぼ同じですが、最も使用頻度の高いサブキャッシュが維持されるところが異なります。サブキャッシュでは、ソフトまたはハード参照を使用して、これらのオブジェクトがガベージ・コレクションの対象とならないように、またはメモリー上でJVMが少ない場合にのみガベージ・コレクションの対象となるようにします。

ソフト・キャッシュとハード・キャッシュでは、より効率的にメモリーを使用できます。これらのマップでは、ガベージ・コレクションされたオブジェクトを解放します(最近使用された一定数のオブジェクトは除く)。弱参照でキャッシュされたオブジェクトは、トランザクションが複数のクライアント/サーバー起動にわたって使用される場合、フラッシュされる可能性があることに注意してください。サブキャッシュのサイズは、@Cache size属性で指定されたキャッシュのサイズに比例します。キャッシュ・サイズは、トランザクションで保持するオブジェクトの数に設定する必要があります。

このキャッシュは、キャッシュで使用されるメモリーを制御する手段として、ほとんどの場合に使用をお薦めします。

8.2.5 NONEおよびCACHE

NONEおよびCACHEオプションでは、オブジェクト・アイデンティティが維持されないため、これらは非常に限定的な状況でのみ使用する必要があります。NONEではどのオブジェクトもキャッシュされません。CACHEでは、LRU方式で一定数のオブジェクトのみがキャッシュされます。これらのキャッシュ・タイプは、オブジェクトに対するリレーションシップが存在しない場合にのみ使用する必要があります。これらのオプションの使用はお薦めしません。キャッシュを無効にするには、かわりにキャッシュ分離をISOLATEDに設定してください。

8.2.6 キャッシュおよびアイデンティティ・マップの構成のガイドライン

キャッシュ・タイプの構成時には、次のガイドラインに従ってください。

  • 存続期間の長いオブジェクトでは、SOFTSOFT_WEAKまたはHARD_WEAKキャッシュ・タイプを使用します。どのような場合にどちらを選択するかについては、8.2.6.1項「WEAK、SOFTおよびHARDキャッシュ・タイプの内部について」を参照してください。

  • 存続期間の短いオブジェクトでは、WEAKキャッシュ・タイプを使用します。

  • インスタンスがほとんど存在しない存続期間の長いオブジェクト(参照データなど)では、FULLキャッシュ・タイプを使用します。


    注意:

    FULLキャッシュ・タイプは、クラスに少数の限られたインスタンスが存在する場合にのみ使用してください。それ以外の場合に使用すると、メモリー・リークが発生します。


  • キャッシュが不要であるか、使用しない場合、キャッシュ分離をISOLATEDに設定して共有キャッシュを無効にします。


    注意:

    CACHEおよびNONEキャッシュ・タイプの使用はお薦めしません。


8.2.6.1項「WEAK、SOFTおよびHARDキャッシュ・タイプの内部について」を参照してください。

8.2.6.1 WEAK、SOFTおよびHARDキャッシュ・タイプの内部について

WEAKおよびSOFTキャッシュ・タイプでは、JVM弱参照およびソフト参照を使用して、アプリケーションによって参照されるオブジェクトがキャッシュ内に保持されるようにします。アプリケーションでオブジェクト参照を解除すると、JVMでは自由にオブジェクトのガベージ・コレクションを実行します。弱参照またはソフト参照がガベージ・コレクションされる時期は、JVMによって決定されます。一般的に、弱参照は、それぞれのJVMガベージ・コレクション操作でガベージ・コレクションされると想定されます。

SOFT_WEAKおよびHARD_WEAKキャッシュ・タイプには、次の2つのキャッシュが含まれます。

  • 参照キャッシュ: それぞれソフトまたはハード参照を含めたLinkedListとして実装されるキャッシュ

  • 弱キャッシュ: 弱参照を含めたMapとして実装されるキャッシュ

指定したサイズでSOFT_WEAKまたはHARD_WEAKキャッシュを作成すると、参照キャッシュのLinkedListは正確にそのサイズになります。弱キャッシュのMapのサイズは、その初期サイズと同じです(指定したサイズより多くのオブジェクトが読み取られると、弱キャッシュは増大します)。EclipseLinkはガベージ・コレクションを制御しないため、弱く保持されたオブジェクトは適切なときにJVMが削除します。

参照キャッシュはLinkedListとして実装されるため、リストの最後に新しいオブジェクトが追加されます。そのため、これは本質的に最低使用頻度(LRU)キャッシュです(固定サイズで、最大サイズに到達するとリストの先頭のオブジェクトが削除されます)。

SOFT_WEAKおよびHARD_WEAKは、基本的に同じタイプのキャッシュです。HARD_WEAKは、一部のJVMでの問題を回避するために構成されました。

アプリケーションを実行しているシステムでメモリー不足の状態が頻繁に発生する場合や、プラットフォームのJVMで弱い参照とソフト参照が同様に扱われる場合には、参照キャッシュ内のオブジェクトのガベージ・コレクションが頻繁に行われるため、参照キャッシュによるパフォーマンス向上の利点は得られません。この場合、HARD_WEAKの使用をお薦めします。これはSOFT_WEAKと同じですが、参照キャッシュでハード参照を使用する点が異なります。そうすることで、アプリケーションは参照キャッシュによるパフォーマンス向上の利点を確実に得ることができます。

HARD_WEAKまたはSOFT_WEAK内のオブジェクトは、参照キャッシュから削除されると、弱キャッシュに格納されます。このオブジェクトは引き続きキャッシュされていますが、JVMは弱参照をガベージ・コレクションすることを随時決定できるため、どれくらいの間キャッシュに保持されるかはEclipseLinkでは保証できません。

8.3 問合せおよびキャッシュについて

共有永続性ユニット(セッション)・キャッシュに対して実行される問合せは、インメモリー問合せと呼ばれます。インメモリー問合せを慎重に構成することで、パフォーマンスを向上できます。

デフォルトでは、主キーに基づいてシングル・オブジェクトを検索する問合せは、必要なオブジェクトをまずキャッシュから取得し、オブジェクトがキャッシュに存在しない場合にのみ、データ・ソースで検索を行います。その他すべての問合せタイプの場合は、デフォルトでデータベースを最初に検索します。特定の問合せを、インメモリー・キャッシュ、データベース、その両方のうち、いずれに対して実行するかを指定できます。

8.3.1 問合せキャッシュ・オプションおよびインメモリー問合せについて

JPAは、問合せの共有永続性ユニット・キャッシュ(L2)との対話方法を構成するため、基本的な問合せヒントを定義しています。EclipseLinkでは、キャッシュの使用を構成するための、追加の問合せヒントも用意されています。JPAおよびEclipseLinkの問合せヒントの詳細は、9.6項「問合せヒントについて」を参照してください。

エンティティにはfind()メソッドまたは問合せのいずれかを使用して、JPAを通じてアクセスできます。The find()メソッドは、最初にIdに対する永続性コンテキスト・キャッシュ(L1)をチェックし、オブジェクトが見つからない場合は共有コンテキスト・ユニット・キャッシュ(L2)をチェックし、それでもオブジェクトが見つからない場合はデータベースにアクセスします。デフォルトでは、IDまたはキャッシュの索引付けされたフィールドを使用する場合を除き、すべての問合せでデータベースにアクセスします。問合せがデータベースから行を取得すると、各行をキャッシュにより解決します。オブジェクトがキャッシュ内に存在する場合は、行は廃棄され、オブジェクトが使用されます。オブジェクトが共有キャッシュ内に存在しない場合は、オブジェクトは行から構築され、共有キャッシュに格納されます。コピーも永続性コンテキストのキャッシュに格納され、問合せ結果として戻されます。

これが一般的なプロセスですが、トランザクションが使用済の場合は異なります。トランザクションが使用済の場合、共有の永続性ユニット・キャッシュは無視され、オブジェクトは永続性コンテキスト・キャッシュに直接格納されます。

次の状況では、トランザクションは使用済とみなされます。

  • flush()がデータベースに変更を書き込んだ場合。

  • ペシミスティック・ロック問合せが実行された場合。

  • 更新または削除問合せが実行された場合。

  • ネイティブSQL問合せが実行された場合。

  • この永続性ユニット・プロパティeclipselink.transaction.join-existingが使用されます。

  • JDBC接続がEntityManagerからアンラップされた場合。

  • UnitOfWork API beginEarlyTransactionが呼び出された場合。

エンティティを構成して独立させたり、キャッシュ不能とすることもでき、このような場合は決して共有キャッシュに格納されません(「共有、独立、保護、弱参照および読取り専用キャッシュ」を参照してください)。

8.4 失効したデータの処理について

失効したデータは、データ・ソースにコミットされた最新バージョンでないオブジェクトをキャッシュした結果として発生します。失効したデータの発生を防止するには、適切なキャッシュ・ロック戦略を実装します。

EclipseLinkでは、デフォルトで、読取りまたは書込み操作中のキャッシュ・ロックを最小限に抑えるために同時実行性が最適化されます。非常に明確な理由があって変更する場合を除き、EclipseLinkの分離レベルはデフォルトのまま使用してください。EclipseLinkでの分離レベルの詳細は、8.1.3項「共有、独立、保護、弱参照および読取り専用キャッシュ」を参照してください。

キャッシュ・ロックにより、プロセスがオブジェクトを読み取る、または書き込むタイミングを制御します。キャッシュ・ロックの構成に応じて、別のプロセス内で使用されているオブジェクトの読取りまたは書込みが可能かどうかが決まります。

キャッシュを適切に管理すると、アプリケーションの効率が高まります。キャッシュはデータベース・アクセスを減少させ、オブジェクト・アイデンティティの管理の重要な部分を占めるため、キャッシュを完全にオフにすることはほとんどありません。

キャッシュ戦略を最大限に活用し、失効したデータがアプリケーションに使用されることを最小限に抑えるために、次のことをお薦めします。

8.4.1 ロック・ポリシーの構成

ロック・ポリシーを構成しておくことで、変更中のオブジェクトの値が変更されるのを防止するか、または少なくとも変更された時間を識別することができます。これは通常、オプティミスティック・ロックを使用して行います。EclipseLinkでは、数値バージョン・フィールド、タイムスタンプ・バージョン・フィールド、一部のフィールド、すべてのフィールドなど、複数のロック・ポリシーでロックできます。オプティミスティック・ロックとペシミスティック・ロックについては、次の項で説明します。

8.4.1.1 オプティミスティック・ロック

EclipseLinkオプティミスティック・ロックの使用をお薦めします。オプティミスティック・ロックを使用した場合、すべてのユーザーにデータへの読取りアクセス権限があります。ユーザーが変更を書き込もうとすると、アプリケーションにより、ユーザーがデータを読み取ってから、そのデータが変更されていないかが確認されます。@OptimisticLockingを使用して、エンティティを更新または削除する際にEclipseLinkが使用するオプティミスティック・ロックのタイプを指定します。

バージョン・ロック・ポリシーまたはフィールド・ロック・ポリシーを使用できます。バージョン・ロック・ポリシーの使用をお薦めします。標準のJPA @Versionの注釈は、単一値の値およびタイムスタンプ・ベースのロックで使用されます。ただし、高度なロッキング機能には、@OptimisticLocking注釈を使用します。@OptimisticLocking注釈には、エンティティを更新または削除する際に使用するオプティミスティック・ロックのタイプを指定します。オプティミスティック・ロックは、@Entityまたは@MappedSuperclass注釈でサポートされています。

OptimisticLocking注釈および使用可能なロックのタイプの詳細は、『Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』の@OptimisticLockingに関する項を参照してください。

詳細は、5.2.4.1項「オプティミスティック・バージョン・ロック・ポリシー」および5.2.4.1.3項「オプティミスティック・フィールド・ロック・ポリシー」を参照してください。

8.4.1.2 ペシミスティック・ロック

ペシミスティック・ロックを使用した場合は、データを更新する目的でそのデータにアクセスする最初のユーザーが、更新を完了するまでデータをロックします。このアプローチの短所は、並行性が損われること、デッドロックになる可能性があることです。eclipselink.pessimistic-lockプロパティを使用して、TopLinkでペシミスティック・ロックを使用するかどうかを指定します。詳細は、『Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』のeclipselink.pessimistic-lockに関する項を参照してください。

問合せレベルでペシミスティック・ロックのサポートを使用することを検討してください。5.2.4.2項「ペシミスティック・ロック・ポリシー」を参照してください。

8.4.2 クラス単位でのキャッシュの構成

特定のクラスで使用するデータを他のアプリケーションが変更できる場合、そのクラスには弱いスタイルのキャッシュを使用します。たとえば、@Cache typeの属性値WEAKおよびSOFT_WEAKを指定すると、参照対象として削除されたオブジェクトをキャッシュが保持する期間は最も短くなります。キャッシュ・タイプの詳細は、8.2項「キャッシュのタイプとサイズについて」を参照してください。

8.4.3 必要時の問合せ単位でのキャッシュ・リフレッシュの強制

すべての問合せには、選択したオブジェクトの最新バージョンをデータ・ソースで検索し、その情報でキャッシュを更新することをEclipseLinkに強制するフラグを含めることができます。詳細は、8.5項「明示的な問合せのリフレッシュについて」を参照してください。Oracle TopLinkのソリューション・ガイドのキャッシュのリフレッシュに関する項も参照してください。

8.4.4 キャッシュの無効化の構成

expiryを使用すると、エンティティ・インスタンスをキャッシュで失効させるまでのミリ秒数や、エンティティ・クラスのすべてのインスタンスをキャッシュで失効させる時刻を指定してエンティティを構成できます。有効期限は、@Cache注釈または<cache XML要素で設定し、expiryまたはexpiryTimOfDay属性で構成できます。詳細は、Oracle TopLinkのソリューション・ガイドのエンティティ・キャッシュの有効期限の設定に関する項を参照してください。

8.4.5 キャッシュ・コーディネーションの構成

アプリケーションが読取り中心で、変更がすべて、複数の分散セッションで実行されている同一Javaアプリケーションによって行われる場合は、EclipseLinkのキャッシュ・コーディネーション機能の使用が有効なことがあります。これは、データの失効は防止しませんが、できるかぎり最小限に抑えます。詳細は、8.9項「キャッシュ・コーディネーションについて」および8.10項「クラスタリングおよびキャッシュ・コーディネーション」を参照してください。

8.5 明示的な問合せのリフレッシュについて

分散システムの中には、システム内のサーバー全体で少数のオブジェクトのみが一貫していればよいものがあります。逆に、いくつかの特定のオブジェクトが、負荷に関係なく、常に最新の状態であることを求めるシステムもあります。そのようなシステムを構築する場合は、分散キャッシュ・コーディネーションを行うほどの負荷をかけずに、データベースから選択したオブジェクトを適切な間隔で明示的にリフレッシュすることができます。

このタイプの戦略を実装するには、次の手順を実行します。

  1. 必要なオブジェクトをリフレッシュする一連の問合せを構成します。

  2. 適切なリフレッシュ・ポリシーを設定します。

  3. 必要に応じて問合せを起動し、オブジェクトをリフレッシュします。

@Cache注釈には、データベースに対するすべての問合せで強制的にキャッシュをリフレッシュさせるalwaysRefresh属性とrefreshOnlyIfNewer属性が用意されています。キャッシュは、データベース内のオプティミスティック・ロック値がキャッシュ内のものよりも実際に新しい場合にのみリフレッシュされます。詳細は、Oracle TopLinkのソリューション・ガイドのキャッシュのリフレッシュに関する項を参照してください。

問合せを実行すると、必要なオブジェクトがキャッシュ内に存在する場合、EclipseLinkは、より新しいバージョンがないかどうかデータベースをチェックすることなく、キャッシュされたオブジェクトを返します。これにより、EclipseLinkがデータベースの結果から作成する必要のあるオブジェクトの数が減るため、この方法はコーディネートされていないキャッシュ環境に最適です。ただし、コーディネートされたキャッシュ環境では必ずしも最善の戦略ではありません。

この動作をオーバーライドするには、alwaysRefresh属性を設定し、データベースのオブジェクトがキャッシュ内のオブジェクトよりも常に優先されるよう指定します。この場合、キャッシュされたオブジェクトがデータベースのデータで更新されます。

このタイプのリフレッシュ・ポリシーは、アプリケーションの特性に応じて、EclipseLinkの各エンティティに実装することも、特定の問合せのみに実装することもできます。

8.6 キャッシュ索引について

EclipseLinkキャッシュは、エンティティのIDで索引付けされます。これによって、ID別のfind()操作、リレーションシップおよび問合せが可能になり、キャッシュ・ヒットを取得してデータベース・アクセスを回避できます。キャッシュは、非ID問合せではデフォルトで使用されません。すべての非ID問合せは、データベースにアクセスし、結果セットで返される行ごとにキャッシュによって解決されます。

アプリケーションは、そのID以外に他の一意キーを各モデルに持つことが多くあります。生成されたIDが使用される場合、これはごく普通です。アプリケーションは、頻繁にこれらの一意キーに基づいて問合せを行うため、これらの問合せ時のデータベース・アクセスを回避するため、キャッシュ・ヒットを取得できる方が便利です。

キャッシュ索引では、EclipseLinkキャッシュ内にインメモリー索引を作成することで、非IDフィールドでキャッシュ・ヒットが可能になります。キャッシュ索引は、単一のフィールドまたはフィールドのセットに配置できます。索引付けされたフィールドは、更新可能です(通常は一意となりますが、これは要件ではありません)。索引付けされたフィールドを含む問合せでは、キャッシュ・ヒットを取得できます。索引付けされた問合せから取得できるのは、単一の結果のみです。

キャッシュ索引は、@CacheIndexおよび@CacheIndexes注釈と、<cache-index> XML要素を使用して構成できます。@CacheIndexは、エンティティに定義するか、属性に定義して属性に索引付けすることができます。エンティティに定義する索引では、索引に使用するcolumnNamesを定義する必要があります。索引は、オブジェクトが更新可能な属性を使用して更新されたときに、再度索引付けするように構成できます。

問合せ結果キャッシュを使用して、索引付けされていない問合せの問合せ結果をキャッシュすることも可能です。詳細は、8.8項「問合せ結果キャッシュについて」を参照してください。

8.7 データベース・イベント通知およびOracle CQN

一部のデータベースおよびデータベース製品では、行が更新または削除された場合、データベースからイベントを発生させることができます。

データベースがデータベースの変更をEclipseLinkに通知できるように、EclipseLinkはAPIをサポートしているため、変更されたオブジェクトはEclipseLinkの共有キャッシュで無効化できます。これにより、他のアプリケーションがデータベース内の同じデータにアクセスする場合でも、共有キャッシュが使用され、失効したデータは回避されます。EclipseLinkは、Database Change Notification CQNに対するOracle Databaseの機能との統合をサポートしています。データベース・イベントをサポートする他のデータベースおよび製品に対して、カスタムのDatabaseEventListenerが提供される場合もあります。

共有環境でのキャッシュについては、次のように他の解決策があります。

JPA Cache APIおよびEclipseLinkのJpaCache APIを直接使用して、共有キャッシュ内のオブジェクトをアプリケーションによって無効化することもできます。EclipseLinkのキャッシュ・コーディネーションは、EclipseLinkの永続化ユニットのクラスタへの無効化メッセージの送信に使用することもできます。

データベース・イベントは、アプリケーションが失効データを取得する可能性を低減できますが、その可能性が排除されることはありません。オプティミスティック・ロックは、引き続きデータの整合性を保証するために使用する必要があります。単一のサーバー・アプリケーションでも、ペシミスティック・ロックが使用される場合を除き、失効データは永続性コンテキスト内で発生する可能性があります。オプティミスティック(またはペシミスティック)・ロックは、任意のマルチユーザー・システムでデータの整合性を保証するために常に必要です。

8.7.1 Oracle連続問合せ通知

Oracle Databaseの10.2リリースでは、連続問合せ通知(CQN)機能がリリースされました。CQNでは、表の列が変更された場合、データベース・イベントを発生させることができます。CQN用のJDBC APIは11.2まで完成しないため、EclipseLinkの統合には11.2が必要です。

EclipseLink CQNのサポートは、Oracle JDBCを受信したデータベース変更イベントと統合するOracleChangeNotificationListenerリスナーによって有効化されます。eclipselink.cache.database-event-listenerプロパティを使用して、リスナーの完全クラス名を構成します。

デフォルトでは、永続性ユニットのすべての表が変更通知のために登録されますが、@Cache注釈のdatabaseChangeNotificationType属性を使用して、変更通知を特定のクラスに対して選択的に無効にするよう構成できます。

Oracle CQNはROWIDを使用し、列レベルの変更を通知します。このためEclipseLinkでは、CQNが有効なクラスのすべての問合せにROWIDを含める必要があります。挿入操作の後、EclipseLinkでは、オブジェクトのROWIDも選択する必要があります。EclipseLinkでは、オブジェクトのIdのみでなく、ROWIDのキャッシュ索引も維持します。EclipseLinkは、トランザクションを処理しているサーバーでキャッシュが無効にされないよう、トランザクションごとに1回データベースのトランザクションIdも選択します。

EclipseLinkのCQN統合には次の制限があります。

  • プライマリ表でバージョンが使用され更新されないかぎり、セカンダリ表のオブジェクトが変更されてもその無効化はトリガーされません。

  • プライマリ表でバージョンが使用され更新されないかぎり、オブジェクトのOneToMany、ManyToManyおよびElementCollectionのリレーションシップが変更されてもその無効化はトリガーされません。

8.8 問合せ結果キャッシュについて

EclipseLinkの問合せ結果キャッシュでは、オブジェクトがキャッシュされる場合と同じように、名前付き問合せの結果をキャッシュできます。

EclipseLinkのデフォルトでは、IDまたはキャッシュの索引付けされたフィールドを使用する場合を除き、すべての問合せでデータベースにアクセスします。結果の行はキャッシュで解決され、オブジェクトがキャッシュされている場合、リレーションシップに対する追加の問合せは回避されますが、元の問合せは常にデータベースにアクセスします。EclipseLinkには、キャッシュを問い合せるオプションがありますが、EclipseLinkではデータベースのすべてのオブジェクトがキャッシュ内に存在するとは想定されないため、これらのオプションはデフォルトでは使用されません。問合せ結果キャッシュでは、索引付けされていない結果リスト問合せでもキャッシュから利点を得ることができます。

問合せ結果キャッシュは、問合せの名前と問合せのパラメータで索引付けされます。結果をキャッシュできるのは名前付き問合せのみで、動的問合せでは問合せ結果キャッシュを使用できません。同様に、ヒントやプロパティを設定するなど、実行前に名前付き問合せを変更すると、キャッシュされた結果を使用できません。

問合せ結果キャッシュでは、オブジェクト・キャッシュのように、アプリケーションからコミット済の変更が選択されません。これは、読取り専用オブジェクトをキャッシュする場合にのみ使用する必要があります(または、失効した結果のキャッシュを回避するために無効化ポリシーを使用する必要があります)。結果セットのオブジェクトに対するコミット済の変更は、選択されますが、結果セットに影響する変更(結果セットから追加または削除する必要のある新規または変更済オブジェクトなど)は選択されません。

問合せ結果キャッシュでは、固定サイズ、キャッシュ・タイプおよび無効化オプションがサポートされます。

8.9 キャッシュ・コーディネーションについて

すべてのアプリケーションのデータを最新の状態に維持する必要性は、分散アプリケーションを構築する際の設計上の大きな課題です。環境内のサーバー数が増加するにつれて、この課題の難しさも増していきます。EclipseLinkには、分散アプリケーションのデータを最新の状態に維持する、分散キャッシュ・コーディネーション機能が用意されています。

キャッシュ・コーディネーションにより、分散アーキテクチャで発生するオプティミスティック・ロック例外の数は減少し、アプリケーションで失敗するトランザクションや繰り返されるトランザクションの数も減少します。とはいえ、キャッシュ・コーディネーションを行っても、効果的なロック・ポリシーが不要になることはありません。最新データが効率的に使用できるように、キャッシュ・コーディネーションはオプティミスティックまたはペシミスティック・ロックとともに使用する必要があります。キャッシュ・コーディネーションは、オプティミスティック・ロック・ポリシーとともに使用することをお薦めします。

EclipseLinkキャッシュをクラスごとにチューニングすると、分散キャッシュ・コーディネーションが不要になります。この設定のチューニングは、キャッシュ・コーディネーションを実装する前に必ず行ってください。詳細は、Oracle TopLinkのソリューション・ガイドのTopLink対応アプリケーションのモニタリングおよび最適化に関する項を参照してください。

キャッシュの無効化を使用すると、キャッシュ・コーディネーションが高速になります。詳細は、Oracle TopLinkのソリューション・ガイドのエンティティ・キャッシュの有効期限の設定に関する項を参照してください。

図8-2に示すように、キャッシュ・コーディネーションは、セッションの複数のインスタンス(大部分の場合、分散されている)が相互にオブジェクト変更をブロードキャストできるようにするセッション機能であり、これにより、各セッションのキャッシュは、最新の状態に保たれるか、次回読み取るデータ・ソースを基にオブジェクトを更新する必要があることを通知されます。


注意:

独立クライアント・セッションは、キャッシュ・コーディネーションと組み合せて使用することはできません。詳細は、8.1.3項「共有、独立、保護、弱参照および読取り専用キャッシュ」を参照してください。


図8-2 コーディネートされた永続性ユニット(セッション)・キャッシュ

図8-2の説明が続きます
「図8-2 コーディネートされた永続化ユニット(セッション)・キャッシュ」の説明

セッションが分散されている場合、つまり、アプリケーションに複数のセッションが含まれている場合(同一JVM内、複数JVM内、あるいは複数サーバー上)、セッションをホスティングしているサーバーがネットワーク上で相互接続されているかぎり、セッションはキャッシュ・コーディネーションに参加できます。検出サービスを必要とするタイプのコーディネート・キャッシュでは、サーバーでユーザー・データグラム・プロトコル(UDP)通信およびマルチキャスト構成がサポートされることも必要です。詳細は、8.10.1項「JMSおよびRMIキャッシュのコーディネーション」を参照してください。

8.9.1 キャッシュ・コーディネーションの使用が必要な場合

キャッシュ・コーディネーションにより、パフォーマンスが向上し、次の特性を持つアプリケーションに対して失効データが発生する可能性が低下します。

  • 変更はすべて、複数の分散セッションで実行されている同一Javaアプリケーションにより実行されます。

  • 読取り中心です。

  • 同一オブジェクトを定期的にリクエストおよび更新します。

これらの特性を持たないアプリケーションでは、パフォーマンスを最大化するため、キャッシュ・コーディネーションを使用しないでください。

失効データの発生頻度を削減する他のオプションについては、8.4項「失効したデータの処理について」を参照してください。

8.10 クラスタリングおよびキャッシュ・コーディネーション

アプリケーション・クラスタは、単一のアプリケーションまたはアプリケーション・セットへのリクエストに対応する中間層サーバー・マシンまたはVMのセットです。複数のサーバーを使用して、アプリケーションのスケーラビリティの向上、またはフォルト・トレランスと高可用性の提供(あるいはその両方)を行います。通常は、同じアプリケーションがクラスタ内のすべてのサーバーにデプロイされ、アプリケーション・リクエストはサーバーのセット全体でロード・バランシングされます。アプリケーション・クラスタは、単一のデータベースまたはデータベース・クラスタにアクセスします。アプリケーション・クラスタでは、新しいサーバーを追加してスケーラビリティを向上したり、更新やサービス提供などのためにサーバーを削除できます。

アプリケーション・クラスタは、Java EEサーバー、WebコンテナまたはJavaサーバー・アプリケーションで構成されます。

EclipseLinkは、任意のクラスタ化環境で動作できます。クラスタ化環境での主な問題は、共有永続性ユニット(L2)・キャッシュの使用です。共有キャッシュ(EclipseLinkプロジェクトではデフォルトで有効)を使用している場合、各サーバーは独自のキャッシュを維持し、各キャッシュ・データは他のサーバーおよびデータベースとの同期を失うことがあります。

EclipseLinkでは、サーバー・キャッシュの同期を保証するために、クラスタ化環境でキャッシュ・コーディネーションが提供されます。

クラスタ化環境でのキャッシュについては、次のように他の多くの解決策があります。

キャッシュ・コーディネーションによって、クラスタ内の異なるサーバー(または同じサーバー)にデプロイされた永続性ユニットのセットで変更を同期できます。キャッシュ・コーディネーションは、クラスタ内の各サーバーの永続性ユニットごとに動作し、トランザクション・オブジェクトの変更通知をクラスタ内の他の永続性ユニットにブロードキャストできます。EclipseLinkでは、RMIおよびJMSを介したキャッシュ・コーディネーションがサポートされます。キャッシュ・コーディネーション・フレームワークは、拡張可能なため、他のオプションを開発することもできます。

EclipseLinkでは、デフォルトで、読取りまたは書込み操作中のキャッシュ・ロックを最小限に抑えるために同時実行性が最適化されます。非常に明確な理由があって変更する場合を除き、EclipseLinkのトランザクション分離構成はデフォルトのまま使用してください。

キャッシュ・コーディネーションは、各トランザクションの変更をクラスタ内の他のサーバーにブロードキャストすることで動作します。他のサーバーは、それぞれ変更通知を受信し、キャッシュ内の変更済オブジェクトを無効化するか、キャッシュ済オブジェクトの状態を変更によって更新します。キャッシュ・コーディネーションは、データベースのコミット後に発生するため、コミット済の変更のみがブロードキャストされます。

キャッシュ・コーディネーションは、アプリケーションが失効データを取得する可能性を大幅に低減しますが、その可能性が排除されることはありません。オプティミスティック・ロックは、引き続きデータの整合性を保証するために使用する必要があります。単一のサーバー・アプリケーションでも、ペシミスティック・ロックが使用される場合を除き、失効データは永続性コンテキスト内で発生する可能性があります。オプティミスティック(またはペシミスティック)・ロックは、任意のマルチユーザー・システムでデータの整合性を保証するために常に必要です。

キャッシュの同期化など、キャッシュ・コーディネーションに関する詳細は、Oracle TopLinkのソリューション・ガイドのキャッシュ・コーディネーションの使用に関する項を参照してください。

8.10.1 JMSおよびRMIキャッシュのコーディネーション

JMSコーディネート・キャッシュの場合は、特定のセッションのコーディネート・キャッシュが起動されると、そのセッションは、自身のJNDIネーミング・サービス情報を使用してJMSサーバーへの接続を検索および作成します。すべての参加セッションが同一JMSサーバー上の同一トピックに接続されると、コーディネート・キャッシュが準備完了状態になります。この時点で、セッションはオブジェクト変更メッセージの送受信を開始できます。この後、同一JMSおよびJNDIネーミング・サービス情報を使用して、同一コーディネート・キャッシュに参加しているすべてのセッションを構成できます。

RMIコーディネート・キャッシュでは、特定のセッションのコーディネート・キャッシュが起動すると、セッションによってネーミング・サービスの接続がバインドされ(RMIレジストリまたはJNDI)、独自のネーミング・サービス情報を含む通知メッセージが作成され、その通知がマルチキャスト・グループにブロードキャストされます。同じマルチキャスト・グループに属するセッションでこの通知が受信されると、通知メッセージのネーミング・サービス情報が使用され、新しく通知されたセッションのコーディネート・キャッシュとの双方向接続が確立されます。この方法ですべての参加セッションが相互接続されると、コーディネート・キャッシュの準備が完了し、その時点でセッションはオブジェクト変更メッセージの送受信を開始できます。その後、セッションがデプロイされているホストを識別するネーミング情報を使用して各セッションを構成できます。

JMSおよびRMIキャッシュ・コーディネーションの構成の詳細は、Oracle TopLinkのソリューション・ガイドの永続性プロパティを使用したJMSキャッシュ・コーディネーションの構成に関する項および永続性プロパティを使用したRMIキャッシュ・コーディネーションの構成に関する項を参照してください。

8.10.2 カスタム・キャッシュのコーディネーション

EclipseLinkのorg.eclipse.persistence.sessions.coordinationパッケージのクラスを使用して、コーディネート・キャッシュに対する独自のカスタム・ソリューションを定義できます。

8.11 クラスタリングおよびキャッシュの一貫性

アプリケーション・サーバー・クラスタにデプロイされたEclipseLinkアプリケーションは、クラスタのスケーラビリティ、ロード・バランシングおよびフェイルオーバーのメリットを受けることができます。これらの機能は、EclipseLinkアプリケーションの可用性を高め、アプリケーションの需要拡大に伴ってスケーリングできます。EclipseLinkのアプリケーションは、アプリケーション・サーバー・クラスタへも、スタンドアロンのサーバー環境と同様にデプロイできます。ただし、アプリケーション・サーバー・クラスタの場合には、キャッシュの一貫性を確保するために、その他に計画や構成を実行する必要があります。

キャッシュの一貫性を確保するために、エンティティ・キャッシュの無効化、キャッシュのリフレッシュ、エンティティ有効期限の設定およびキャッシュのオプティミスティック・ロックの設定などのタスクを実行します。詳細は、Oracle TopLinkのソリューション・ガイドのタスク1: キャッシュの一貫性の構成を参照してください。

8.12 キャッシュ・インターセプタ

EclipseLinkでは、非常に機能的で、高性能な統合されたキャッシュが用意されています。ただし、EclipseLinkのCacheInterceptor注釈を使用して、サードパーティの外部キャッシュを統合することができます。

8.13 Coherenceキャッシュの使用

Oracle TopLink Gridは、EclipseLink JPAおよびCoherenceキャッシュの統合を可能にするOracle TopLinkの機能です。標準のJPAアプリケーションは、プライマリ・データ・ストア(一般的にリレーショナル・データベース)と直接対話します。ただし、TopLink Gridの場合、ドメイン・モデルの一部またはすべてをCoherenceデータ・グリッドに格納できます。この構成は、グリッド基盤のJPAとも呼ばれています。

CoherenceキャッシュおよびTopLink Gridを使用して可用性を高め、アプリケーションをスケール・アウトする方法については、Oracle TopLinkのソリューション・ガイドのTopLink GridでのOracle Coherenceを使用したJPAアプリケーションのスケーリングに関する項を参照してください。

TopLink Gridの構成の完全な詳細およびTopLink Gridを使用したアプリケーション開発については、『Oracle Coherenceの統合』のTopLink GridとOracle Coherenceの統合に関する項を参照してください。Oracle TopLink Java APIリファレンスoracle.eclipselink.coherence.* APIに関する項も参照してください。