ヘッダーをスキップ
Oracle Coherenceクライアント・ガイド
リリース3.5
B56041-01
  目次
目次

戻る
戻る
 
次へ
次へ
 

9 C++クライアントに対する連続問合せの実行

Coherenceでは、Coherenceキャッシュからポイント・イン・タイムの問合せ結果を取得でき、その問合せ結果を変更するイベントを受信できる一方、問合せ結果と連続的な関連するイベント・ストリームとを組み合せて、最新の問合せ結果をリアルタイムに維持することもできます。目的の問合せの待機時間が0である場合と同じ効果を持ち、問合せがミリ秒ごとに数回繰り返されるため、この機能は連続問合せと呼ばれています。

連続問合せキャッシュは、Oracleデータベースのマテリアライズド・ビューに似ています。マテリアライズド・ビューでは、データベース表に問い合せたデータがビューにコピーされます。データベース内のデータが変更されると、ビュー内のデータが自動的に更新されます。これにより、結果セットに対する変更を確認できます。連続問合せでは、クライアント上にキャッシュのローカル・コピーが作成されます。フィルタを使用することで、キャッシュのサイズと内容を制限できます。イベント・リスナーを組み合せることで、キャッシュをリアルタイムに更新できます。

たとえば、複数の顧客のすべての発注をリアルタイムに監視するとします。そのためには、連続問合せキャッシュを作成し、対象の顧客に関係するあらゆるイベントをリスニングするイベント・リスナーを設定します。Coherenceは、グリッド上で個々の顧客に関係するデータ・オブジェクトをすべて問い合せ、そのオブジェクトをローカル・キャッシュにコピーします。この問合せのイベント・リスナーでは、その顧客に対してグリッドで行われるあらゆる挿入、更新または削除がリスニングされます。イベントが発生すると、顧客データのローカル・コピーが更新されます。

連続問合せキャッシュの用途

連続問合せキャッシュには、いくつかの異なる一般的な用途があります。

Coherence*Extend機能を連続問合せキャッシュと組み合せることにより、アプリケーションで文字どおり何万もの同時ユーザーをサポートできます。


注意:

連続問合せキャッシュは、分散される可能性のあるより大きなキャッシュ・データセットの特定のサブセットについて、その最新のローカル・コピーを非常に簡単かつ効果的に維持する機能を提供します。そのため、クライアントベースおよびサーバーベースのアプリケーションを含め、ほとんどすべてのタイプのアプリケーションに有用です。

Coherence連続問合せキャッシュ

Coherenceでの連続問合せの実装には、ContinuousQueryCacheクラスを使用します。このクラスは、Coherenceのすべてのキャッシュと同様、次の機能を備えた標準のNamedCacheインタフェースを実装します。

ContinuousQueryCacheは、Coherenceのすべてのキャッシュで提供されるAPIであるNamedCacheインタフェースを実装しているため、非常に使いやすく、その機能が必要になった場合に別のキャッシュと簡単に置き換えることができます。

連続問合せキャッシュの定義

連続問合せキャッシュは、次の2つの機能で定義されます。

基礎となるキャッシュには、別の連続問合せキャッシュを含めた任意のCoherenceキャッシュを使用できます。キャッシュを取得する最も簡単な方法は、CacheFactoryクラスを使用することです。このクラスを使用すると、名前を指定するだけでキャッシュを作成できます。キャッシュは自動的に作成され、アプリケーションのキャッシュ・コンフィギュレーション要素に基づいて構成されます。たとえば、次のコード行ではordersという名前のキャッシュが作成されます。

NamedCache::Handle hCache = CacheFactory::getCache("orders");

この問合せは、他のキャッシュの問合せに使用される問合せと同じタイプです。例9-1は、コード・フィルタを使用して、特定の注文ステータスにある特定のトレーダーを検出する方法を示しています。

例9-1 フィルタを使用した問合せ

ValueExtractor::Handle hTraderExtractor = ReflectionExtractor::create("getTrader");
ValueExtractor::Handle hStatusExtractor = ReflectionExtractor::create("getStatus");

Filter::Handle hFilter = AndFilter::create(EqualsFilter::create(hTraderExtractor, vTraderId),
                              EqualsFilter::create(hStatusExtractor, vStatus));

通常、キャッシュを問い合せるには、QueryMapクラスのメソッドのいずれかを使用します。たとえば、このトレーダーの未決済ポジションすべてのスナップショットを取得するには、次のコードを使用します。

Set::View vSetOpenTrades = hCache->entrySet(hFilter);

これに対し、連続問合せキャッシュはContinuousQueryCache::createメソッドでキャッシュとフィルタを渡すことによって構成されます。

ContinuousQueryCache::Handle hCacheOpenTrades  = ContinuousQueryCache::create(hCache, hFilter);

連続問合せキャッシュに関連付けられたリソースのクリーンアップ

連続問合せキャッシュでは、その基礎となるキャッシュに1つ以上のイベント・リスナーが配置されます。連続問合せキャッシュがアプリケーションの継続期間を通して使用される場合、リソースはそのノードがシャットダウンされたとき、または停止したときにクリーンアップされます。ただし、連続問合せキャッシュがわずかの間だけ使用される場合は、使い終わった時点で連続問合せキャッシュに対してアプリケーションからrelease()メソッドをコールする必要があります。

キーのみのキャッシングまたはキーと値のキャッシング

連続問合せキャッシュを構成する際、問合せで取得されたキーだけをキャッシュで追跡し、要求された場合にのみ、その値を基礎となるキャッシュから取得するように指定することができます。この機能は、問合せの結果セットが非常に膨大になる連続問合せキャッシュを作成する場合、または値をリクエストされることがないか、ほとんどない場合に役立ちます。キーのみをキャッシュするように指定するには、ContinuousQueryCacheを作成する際に、次の例のようにfalseを渡します。

ContinuousQueryCache::Handle hCacheOpenTrades  =
        ContinuousQueryCache::create(hCache, hFilter, false);

次の例に示すように、必要に応じて、キャッシュがインスタンス化された後にCacheValuesプロパティを変更することもできます。

hCacheOpenTrades->setCacheValues(true);

CacheValuesプロパティとイベント・リスナー

連続問合せキャッシュに標準の(非Lite)イベント・リスナーがある場合、またはイベント・リスナーのいずれかがフィルタリングされる場合は、CacheValuesプロパティが自動的にtrueに設定されます。これは、イベントをフィルタリングする際、および発生させたイベントに古い値と新しい値を提供する際に、ローカルにキャッシュされた値を連続問合せキャッシュが使用するためです。

連続問合せキャッシュでのReflectionExtractorの使用

連続問合せキャッシュが値をキャッシュするように構成されている場合は、ReflectionExtractorの使用がサポートされません。これは、ReflectionExtractorではC++でのリフレクションがサポートされていないためです。この場合は、カスタム・エクストラクタを用意する必要があります。連続問合せキャッシュで値がローカルにキャッシュされていない場合は、ReflectionExtractorを使用できます。これは、このエクストラクタがクライアントで抽出を実行せず、かわりに必要な抽出情報をクラスタに渡して問合せを実行するためです。

連続問合せキャッシュのリスニング

連続問合せキャッシュ自体は監視可能であるため、クライアントが連続問合せキャッシュに1つ以上のイベント・リスナーを配置することが可能です。次に例を示します。

例9-2 連続問合せキャッシュへのリスナーの配置

ContinuousQueryCache::Handle hCacheOpenTrades  = ContinuousQueryCache::create(hCache, hFilter);
hCacheOpenTrades->addFilterListener(hListener);

すでにキャッシュに格納されているすべてのアイテム、およびキャッシュに追加されるすべてのアイテムに対して、アプリケーションでなんらかの処理を実行する必要がある場合は、作成中にリスナーを設定します。連続問合せキャッシュ内のアイテムが(問合せに含まれていたため)最初から存在していたか、キャッシュの作成中または作成後に追加されたかに関係なく、作成されたキャッシュはアイテムごとに1つのイベントを受信します。ContinuousQueryCacheのファクトリ作成メソッドには、キャッシュ、フィルタおよびリスナーを指定できる形式があります。

例9-3 フィルタとリスナーを使用する連続問合せキャッシュの作成

ContinuousQueryCache::Handle hCacheOpenTrades  = ContinuousQueryCache::create(
        hRemoteCache, hFilter, true, hListener);

予期しない結果の回避

連続問合せキャッシュ内のアイテムを処理するには2つのアプローチがありますが、どちらも予期しない結果や望ましくない結果をもたらす場合があります。まず、処理を実行した後、その後の追加に対応するためにリスナーを追加すると、反復処理が終了してリスナーが追加されるまでのわずかの時間に発生したイベントを見逃すことになります。これを例9-4に示します。

例9-4 データを処理してからリスナーを追加する場合

ContinuousQueryCache::Handle hCacheOpenTrades  = ContinuousQueryCache::create(hCache, hFilter);

for (Iterator::Handle hIter = hCacheOpenTrades->entrySet()->iterator(); hIter->hasNext(); )
    {
    Map::Entry::View vEntry = cast<Map::Entry::View>(hIter->next());
    // .. process the cache entry
    }
hCacheOpenTrades->addFilterListener(hListener);

2番目のアプローチでは、イベントを見逃さないように、まずリスナーを追加し、その後で処理を実行します。この場合、イベントとイテレータの両方に同じエントリが出現する可能性があります。イベントは非同期の可能性があるため、操作の順序は保証されません。

例9-5 リスナーを追加してからデータを処理する場合

ContinuousQueryCache::Handle hCacheOpenTrades  =
        ContinuousQueryCache::create(hRemoteCache, hFilter);

hCacheOpenTrades->addFilterListener(hListener);
for (Iterator::Handle hIter = hCacheOpenTrades->entrySet()->iterator(); hIter->hasNext(); )
    {
    Map::Entry::View vEntry = cast<Map::Entry::View>(hIter->next());
    // .. process the cache entry
    }

安定したマテリアライズド・ビューの実現

連続問合せキャッシュの実装でも同じ課題に直面していました。その課題とは、基礎となるキャッシュから変更イベント・ストリームを受信しながら、その同じキャッシュの正確なポイント・イン・タイム・スナップショットを組み立てる方法です。その解決法は、いくつかの部分に分かれています。第1に、Coherenceでは同期イベントのオプションがサポートされ、それによって一連の順序保証が実現します。第2に、連続問合せキャッシュでは、その初期移入の実装が2つのフェーズに分かれているため、まず基礎となるキャッシュに対して問合せを実行し、その後、最初のフェーズ中に発生したイベントをすべて解決できます。このようにイベントを見逃したり重複させたりすることなくデータの可視性を保証する操作はかなり複雑であるため、ContinuousQueryCacheでは、アプリケーション開発者が作成時にリスナーを渡すことで、この複雑さに対処しなくても済むようにしています。

同期リスナーおよび非同期リスナーのサポート

デフォルトでは、連続問合せキャッシュに対するリスナーによって、リスナーのイベントが非同期に配信されます。ただし、ContinuousQueryCache実装では、SynchronousListenerインタフェースで規定されているとおり、同期イベントのオプションが考慮されます。

連続問合せキャッシュを読取り専用にする

連続問合せキャッシュは読取り専用キャッシュにすることができます。そのためには、次の例のように、ContinuousQueryCacheクラスのブール・メソッドsetReadOnlyを使用します。

hCacheOpenTrades->setReadOnly(true);

読取り専用の連続問合せキャッシュでは、オブジェクトの追加、変更、削除またはロックができません。

連続問合せキャッシュを読取り専用に設定した後は、読取り/書込みに戻すことはできません。