ヘッダーをスキップ
Oracle® Coherence開発者ガイド
リリース3.6.1
B61368-02
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

21 連続問合せキャッシュの使用方法

Coherenceキャッシュからポイント・イン・タイムの問合せ結果を取得でき、その問合せ結果を変更するイベントを受信可能な場合、Coherenceでは、問合せ結果と連続的な関連するイベント・ストリームとを組み合せて、問合せ結果をリアルタイムに維持できます。目的の問合せの待機時間が0である場合と同じ効果を持ち、問合せがミリ秒ごとに数回繰り返されるため、この機能は連続問合せと呼ばれています。ポイント・イン・タイムの問合せ結果およびイベントの詳細は、第20章「キャッシュ内のデータの問合せ」を参照してください。

Coherenceでは、問合せの結果を連続問合せキャッシュにマテリアライズし、問合せでイベント・リスナーを使用してリアルタイムでキャッシュを最新の状態に保つことにより、連続問合せ機能を実装します。つまり、Coherenceの連続問合せは、決して古くなることのない、キャッシュされた問合せ結果になります。

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

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

使用例の1つにトレーディング・システム・デスクトップがあります。このデスクトップには、トレーダーの未処理の注文とすべての関連情報が常に最新の状態で保持されている必要があります。Coherence*Extend機能を連続問合せキャッシュと組み合せることにより、アプリケーションで文字どおり何万もの同時ユーザーをサポートできます。


注意:

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

Coherence連続問合せキャッシュ

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

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

連続問合せキャッシュの構成

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

  1. 基礎となるキャッシュ

  2. 連続問合せキャッシュでキャッシュされるサブセットを構成する、基礎となるキャッシュの問合せ

基礎となるキャッシュには、別の連続問合せキャッシュを含めた任意のCoherenceキャッシュを使用できます。キャッシュは一般にCacheFactoryで取得されます。これにより開発者は、次の例に示すように、キャッシュの名前を指定するだけでアプリケーションのキャッシュ構成情報に基づいて自動的にキャッシュを構成できます。

NamedCache cache = CacheFactory.getCache("orders");

キャッシュ構成情報の指定方法の詳細は、付録B「キャッシュ構成の要素」を参照してください。

この問合せは、次の用途で使用される問合せと同じタイプになります。

例21-1 連続問合せキャッシュの問合せ

Filter filter = new AndFilter(new EqualsFilter("getTrader", traderid),
                              new EqualsFilter("getStatus", Status.OPEN));

問合せの詳細は、第20章「キャッシュ内のデータの問合せ」を参照してください。

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

例21-2 連続問合せキャッシュのデータの取得

Set setOpenTrades = cache.entrySet(filter);

同様に、連続問合せキャッシュは、次に示す同じ2つの要素で構成されます。

例21-3 連続問合せキャッシュの構成

ContinuousQueryCache cacheOpenTrades = new ContinuousQueryCache(cache, filter);

ContinuousQueryCacheに関連付けられているリソースのクリーンアップ

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

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

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

例21-4 CacheValuesプロパティを構成できるコンストラクタ

ContinuousQueryCache cacheOpenTrades = new ContinuousQueryCache(cache, filter, false);

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

例21-5 CacheValuesプロパティの設定

cacheOpenTrades.setCacheValues(true);

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

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

ContinuousQueryCacheのリスニング

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

例21-6 連続問合せキャッシュへのリスナーの追加

ContinuousQueryCache cacheOpenTrades = new ContinuousQueryCache(cache, filter);
cacheOpenTrades.addMapListener(listener);

すでにキャッシュに格納されているすべてのアイテムとキャッシュに追加されるすべてのアイテムに対してなんらかの処理を実行する必要がある場合、その方法は2つあります。1つは、処理を実行した後、以降の追加に対処するリスナーを追加する方法です。

例21-7 連続問合せキャッシュ・エントリの処理とリスナーの追加

ContinuousQueryCache cacheOpenTrades = new ContinuousQueryCache(cache, filter);
for (Iterator iter = cacheOpenTrades.entrySet().iterator(); iter.hasNext(); )
    {
    Map.Entry entry = (Map.Entry) iter.next();
    // .. process the cache entry
    }
cacheOpenTrades.addMapListener(listener);

ただし、このコードは正しくありません。これでは、反復処理が終了してリスナーが追加されるまでのわずかの時間に発生したイベントを見逃すことになります。別の方法では、イベントを見逃さないように、まずリスナーを追加し、その後で処理を実行します。

例21-8 リスナー追加後の連続問合せキャッシュ・エントリの処理

ContinuousQueryCache cacheOpenTrades = new ContinuousQueryCache(cache, filter);
cacheOpenTrades.addMapListener(listener);
for (Iterator iter = cacheOpenTrades.entrySet().iterator(); iter.hasNext(); )
    {
    Map.Entry entry = (Map.Entry) iter.next();
    // .. process the cache entry
    }

ただし、同じエントリがイベント内とIterator内の両方に出現し、イベントが非同期になる可能性があるため、操作の順序が正しいことは保証できません。

解決策は、構成時にリスナーを指定することです。そうすることで、既存の(問合せに含まれていた)項目であるか、キャッシュの構成時または構成後に追加された項目かどうかに関係なく、連続問合せキャッシュ内の項目ごとにイベントが1つずつリスナーに送信されます。

例21-9 連続問合せキャッシュ構成時のリスナーの指定

ContinuousQueryCache cacheOpenTrades = new ContinuousQueryCache(cache, filter, listener);

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

ContinuousQueryCache実装にも同じ課題がありました。同じキャッシュから変更イベントのストリームを受信しながら、基礎となるキャッシュの正確なポイント・イン・タイム・スナップショットをいかにアセンブルするかということです。その解決法は、いくつかの部分に分かれています。まず、Coherenceでは同期イベントのオプションがサポートされており、これによって順序付けが保証されます。このオプションの詳細は、第19章「キャッシュ・イベントの使用方法」を参照してください。

また、ContinuousQueryCacheには初期移入の2フェーズ実装があります。これにより、基礎となるキャッシュを問い合せてから、第1フェーズで発生したすべてのイベントを解決することができます。このようにイベントを見逃したり重複させたりすることなくデータの可視性を保証する操作はかなり複雑であるため、ContinuousQueryCacheでは、アプリケーション開発者が作成時にリスナーを渡すことで、この複雑さに対処しなくても済むようにしています。

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

デフォルトでは、ContinuousQueryCacheのリスナーにはイベントが非同期で配信されます。ただし、ContinuousQueryCacheでは、SynchronousListenerインタフェースで提供されている同期イベントのオプションも対応しています。このオプションの詳細は、第19章「キャッシュ・イベントの使用方法」を参照してください。

ContinuousQueryCacheを読取り専用にする設定

ContinuousQueryCacheは、次のように読取り専用キャッシュにすることができます。

例21-10 ContinuousQueryCacheを読取り専用にする設定

cacheOpenTrades.setReadOnly(true);

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

読取り専用に設定したContinuousQueryCacheを、読取り/書込みに戻すことはできません。