この章の内容は次のとおりです。
Coherenceでは、リエントラント・コールがサポートされていません。リエントラント・サービス・コールは、サービス・スレッドがリクエストを処理しようとするときにその同じサービスに対してリクエストが行われると発生します。サービスに対するリクエストはすべてインバウンド・キューを使用して配信され、Coherenceはリクエストごとに1スレッドのモデルを使用するため、リエントラント・リクエストのそれぞれが他のスレッドを消費することになります(レスポンスを待っている間はコール側のスレッドがブロックします)。用語としては再帰型に似ていますが、概念が異なるため区別する必要があります。
Coherenceのアーキテクチャは、サービスの集合に基づいています。Coherenceの各サービスは、関連付けられた構成とともに、サービスを実装するCoherenceコードで構成されています。サービスは、リクエストを受信してレスポンスを返すキューが関連付けられているスレッドの割当てプールで実行されます。
サービスは、サービス名とサービス・タイプ(起動、レプリケート、分散など)の一意の組合せとして定義されます。たとえば、分散サービスDist-Customers
からDist-Inventory
という名前の分散サービスをコールしたり、Dist-Customers
という名前の分散サービスからRepl-Catalog
という名前のレプリケート・サービスをコールできます。サービス名は、<service-name>
要素を使用して、キャッシュ構成ファイルで構成されます。
Coherenceの現在の実装では、コールがローカルであるかリモートであるかは重要ではありません。このため、親子関係の構築の効率化をサポートするキー・アソシエーションの使用法が複雑になります。キー・アソシエーションを使用して親オブジェクトとそのすべての子オブジェクトを共存させる場合は、親オブジェクトにEntryProcessor
を送信して、そのEntryProcessor
で(ローカルの)子オブジェクトを把握することはできません。これは、子オブジェクトが処理中である場合も同様です。
親オブジェクトと子オブジェクトの両方にアクセスするには、次のいずれかの方法を使用できます。
子オブジェクトを親オブジェクトに埋め込みます(集約パターンを使用)、または
サーバー側のバッキング・マップへの直接アクセスを使用します(安全に実行するには高度な知識が必要です)、または
別のサービス(たとえば、PartitionedService.getKeyOwner
を使用することでターゲット指定される起動)でロジックを実行し、そのサービスからNamedCache
インタフェースを使用してデータにアクセスします、または
リエントラント・コールが可能な別のサービスに子オブジェクトを配置します(ただし、複数の異なるキャッシュ・サービスのパーティション間にはアフィニティがないためネットワーク・アクセスが発生します)。
ほとんどの使用状況では、集約パターンの使用が最適な方法になります。ただし、この方法が(サイズの制限などによって)現実的でなく、クライアント/サーバー・モデルを使用しないで親オブジェクトと子オブジェクトの両方にアクセスする必要がある場合には、起動サービスを使用する方法が、大半の用途で最適な解決方法になります。
リエントラントが許容される場合も、スレッド・プールの飽和および壊滅的なデッドロックが発生する可能性を慎重に回避する必要があります。たとえば、サービスAがサービスBをコールし、サービスBがサービスAをコールする場合、同時コールが多数発生して、スレッド・プールで使用される構成済のスレッドが最大になり、一種のデッドロックが発生する可能性があります。従来のロックと同様、アクセスに順序付けすること(たとえば、サービスAはサービスBのコールが可能であるが、サービスBはサービスAをコールできないようにする)が回避に役立ちます。また、動的なスレッド・プールに依存することが役立つ場合もあります。
したがって、次のようになります。
サービスAからサービスAをコールすることは許されません
サービスAからサービスBをコールし、サービスBからサービスAをコールすることは技術的には可能ですが、デッドロックが発生しやすくなるため、可能なかぎり回避する必要があります。
サービスAがサービスBを、サービスBがサービスCを、サービスCがサービスAをコールすることは、同様に制限されます
サービスAからサービスBをコールすることは許されます
サービスAがサービスBを、サービスBがサービスCを、サービスAがサービスCをコールすることは、同様に許されます
サービス・スレッドは、Coherence APIリクエストの実現に関連するスレッドとして定義されます。サービス・スレッドは、次のエンティティのいずれかを起動できます。
マップ・リスナー
メンバーシップ・リスナー
カスタムのシリアライズ/デシリアライズ(ExternalizableLite
実装など)
バッキング・マップ・リスナー
CacheLoader
/CacheStore
モジュール
問合せロジック(Aggregators
、Filters
、ValueExtractors
、Comparators
など)
エントリ・プロセッサ
トリガー
InvocationService
起動可能ファイル
これらのエンティティは、自己のサービスに対するリエントラント・コールを行いません。