プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle Coherenceでのアプリケーションの開発
12c (12.2.1)
E69903-02
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

27 ライブ・イベントの使用

この章では、ライブ・イベントについて説明し、イベント・インターセプタを使用してイベントが通知されるようにする方法を説明します。アプリケーションはライブ・イベントを使用して、クラスタ操作に対する反応をアプリケーション・ロジックで返します。

この章には次の項が含まれます:

27.1 ライブ・イベントの概要

Coherenceでは、データ・グリッドに対する操作を実行する際にクラスタ内での拡張を可能にするイベント・プログラミング・モデルが提供されます。このモデルでは、監視可能なクラスタ操作の発生を表すイベントを使用します。現在サポートされているイベントは次のとおりです。

  • パーティション・キャッシュ・イベント - キャッシュ内の一連のエントリに対して実行されている操作を表す一連のイベント。パーティション・キャッシュ・イベントには、エントリ・イベントとエントリ・プロセッサ・イベントの両方が含まれます。エントリ・イベントは、キャッシュのエントリの挿入、削除および更新に関連しています。エントリ・プロセッサ・イベントは、エントリ・プロセッサの実行に関連しています。

  • パーティション・キャッシュ・ライフサイクル・イベント – キャッシュの作成、破棄、キャッシュからのすべてのエントリのクリアの操作を表す一連のイベント。

  • パーティション・サービス・イベント - パーティション・サービスによって実行されている操作を表す一連のイベント。パーティション・サービス・イベントには、パーティション転送イベントとパーティション・トランザクション・イベントの両方が含まれます。パーティション転送イベントは、クラスタ・メンバー間のパーティションの移動に関連しています。パーティション・トランザクション・イベントは、複数のキャッシュにまたがる可能性がある変更に関連し、単一のリクエストのコンテキスト内で実行されます。

  • ライフサイクル・イベント - ConfigurableCacheFactoryインスタンスのアクティブ化および破棄を表す一連のイベント。

  • フェデレーション・イベント: フェデレーション・サービスによって実行されている操作を表す一連のイベント。フェデレーション・イベントには、フェデレーテッド接続イベントとフェデレーテッド変更イベントの両方が含まれます。フェデレーテッド接続イベントは、フェデレーテッド参加者の相互作用に関連し、フェデレーテッド変更イベントはキャッシュ更新に関連します。

アプリケーションは、イベントを使用するためにイベント・インターセプタを作成および登録します。イベント・インターセプタは、イベントを処理し、必要に応じて任意のカスタム・ロジックを実装します。イベントには、そのイベントの受信時に可変アクションを実行できるかどうかを制御する様々なルールがあります。

27.2 ライブ・イベント・タイプの理解

イベント・タイプは、クラスタ操作の監視可能な発生を表します。アプリケーションは、イベント・インターセプタを使用してイベントを処理し、イベント・タイプに基づいてどのアクションを実行するのかを決定します。この項では、サポートされている各イベント・タイプを、イベントが発生する機能領域に従って分類して説明します。

この項には、次のトピックが含まれます:

27.2.1 パーティション・キャッシュ・イベントの理解

パーティション・キャッシュ・イベントは、キャッシュ内の一連のエントリに対して実行される操作を表します。パーティション・キャッシュ・イベントには、エントリ・イベント(EntryEvent)とエントリ・プロセッサ・イベント(EntryProcessorEvent)が含まれます。これらのイベントは、com.tangosol.net.events.partition.cacheパッケージ内で定義されます。

27.2.1.1 エントリ・イベント

エントリ・イベントは、キャッシュのエントリの挿入、削除および更新の操作を表します。プリコミット・エントリ・イベント(INSERTINGREMOVINGおよびUPDATING)は操作が実行される前に発生し、エントリに対する変更を許可します。エントリを変更する際は、次の事項が当てはまります。

  • プリコミット・エントリ・イベントに対して登録されているイベント・インターセプタが同期して呼び出されます。

  • 同時更新を防止するために、イベントの処理中は各エントリに対してロックが保持されます。

  • 例外がスローされると、操作がコミットされなくなります。

ポストコミット・エントリ・イベント(INSERTEDREMOVEDおよびUPDATED)は、操作が実行された後に、イベントの発生と同じ順序で発生します。ポストコミット・イベントは、エントリがそれ以降変更できないことを示します。ポストコミット・エントリ・イベントのイベント・インターセプタは、非同期に処理されます。

表27-1は、エントリ・イベント・タイプを示しています。

表27-1 エントリ・イベント

イベント・タイプ 説明

INSERTING

1つ以上のエントリが、キャッシュに挿入されようとしていることを示します。

INSERTED

1つ以上のエントリが、キャッシュに挿入されたことを示します。

REMOVING

1つ以上のエントリが、キャッシュから削除されようとしていることを示します。

REMOVED

1つ以上のエントリが、キャッシュから削除されたことを示します。

UPDATING

1つ以上のエントリが、キャッシュで更新されようとしていることを示します。

UPDATED

1つ以上のエントリが、キャッシュで更新されたことを示します。


27.2.1.2 エントリ・プロセッサ・イベント

エントリ・プロセッサ・イベントは、一連のバイナリ・エントリに対するエントリ・プロセッサの実行を表します。プリコミット・エントリ・プロセッサ・イベント(EXECUTING)は、エントリ・プロセッサが実行される前に発生し、エントリ・プロセッサ・インスタンスに対する変更を許可します。エントリ・プロセッサを変更する際は、次の事項が当てはまります。

  • プリコミット・エントリ・プロセッサ・イベントに対して登録されているイベント・インターセプタが同期して呼び出されます。

  • エントリ・プロセッサは複数のスレッドで共有できます。したがって、エントリ・プロセッサを変更するときはスレッド・セーフティを確保してください。

  • 同時更新を防止するために、イベントの処理中は各エントリに対してロックが保持されます。

  • 例外がスローされると、エントリ・プロセッサが実行されなくなります。

ポストコミット・エントリ・プロセッサ・イベント(EXECUTED)は、エントリ・プロセッサが実行された後に、イベントの発生と同じ順序で発生します。ポストコミット・イベントは、エントリがそれ以降変更できないことを示します。ポストコミット・エントリ・プロセッサ・イベントのイベント・インターセプタは、非同期に処理されます。

表27-2は、エントリ・プロセッサ・イベント・タイプを示しています。

表27-2 エントリ・プロセッサ・イベント

イベント・タイプ 説明

EXECUTING

エントリ・プロセッサが、一連のエントリに対して実行されようとしていることを示します。

EXECUTED

エントリ・プロセッサが、一連のエントリに対して実行されたことを示します。


27.2.2 パーティション・キャッシュ・ライフサイクル・イベントの理解

パーティション・キャッシュ・ライフサイクル・イベント(CacheLifecycleEvent)は、パーティション・キャッシュの作成、破棄および切捨てを表します。これらのイベントは、com.tangosol.net.events.partition.cacheパッケージ内で定義されます。

パーティション・キャッシュ・ライフサイクル・イベントは、パーティション・キャッシュの作成、破棄(NamedCache.destory)または切捨て(NamedCache.truncate)後に発生します。TRUNCATEDイベントには、キャッシュから削除されるエントリは含まれません。

表27-3 パーティション・キャッシュ・ライフサイクル・イベント

イベント・タイプ 説明

CREATED

指定されたキャッシュの記憶域が作成されたことを示します。

DESTROYED

指定されたキャッシュの記憶域が破棄されたことを示します。

TRUNCATED

指定されたキャッシュのすべてのマッピングが記憶域から削除されたことを示します。


27.2.3 パーティション・サービス・イベントの理解

パーティション・サービス・イベントは、パーティション・サービスによって実行されている操作を表します。パーティション・サービス・イベントには、転送イベント(TransferEvent)とトランザクション・イベント(TransactionEvent)が含まれます。これらのイベントは、com.tangosol.net.events.partitionパッケージ内で定義されます。

27.2.3.1 転送イベント

パーティション・サービス転送イベントは、記憶域が有効なメンバー間のパーティションの転送を表します。イベントには、転送が実行されるサービス名、パーティションID、転送に関与するクラスタ・メンバー、およびキャッシュ名とエントリのマップが含まれています。これらのエントリは変更できません。


注意:

転送イベントは、転送されるパーティションに対する操作をすべてブロックするロックが、そのパーティションに対して保持されている間に発生します。

表27-4は、遷移イベント・タイプを示しています。

表27-4 遷移イベント

イベント・タイプ 説明

DEPARTING

一連のエントリが、現在のメンバーから転送中であることを示します。

ARRIVED

一連のエントリが、現在のメンバーに転送されたこと、または現在のメンバーによってリストアされたことを示します。


27.2.3.2 トランザクション・イベント

パーティション・サービス・トランザクション・イベントは、単一のサービス・リクエストのコンテキストで行われる、(場合によっては複数のキャッシュからの)バイナリ・エントリに対する変更を表します。プリコミット・トランザクション・イベント(COMMITTING)は、操作が実行される前に発生し、エントリに対する変更を許可します。エントリを変更する際は、次の事項が当てはまります。

  • 同時更新を防止するために、イベントの処理中は各エントリに対してロックが保持されます。

  • 例外がスローされると、操作がコミットされなくなります。

ポストコミット・トランザクション・イベント(COMMITTED)は、操作が実行された後に発生します。ポストコミット・イベントは、エントリがそれ以降変更できないことを示します。

表27-5は、トランザクション・イベント・タイプを示しています。

表27-5 トランザクション・イベント

イベント・タイプ 説明

COMMITTING

エントリが、それぞれのキャッシュに挿入されようとしていることを示します。

COMMITTED

エントリが、それぞれのキャッシュに挿入されたことを示します。


27.2.4 ライフサイクル・イベントの理解

ライフサイクル・イベント(LifecycleEvent)は、ConfigurableCacheFactoryインスタンスに対して発生したアクションを表します。これらのイベントは、com.tangosol.net.events.applicationパッケージ内で定義されます。

ACTIVATEDイベントは、キャッシュ・ファクトリに関連付けられているすべてのサービスが起動された後に発生します。これらのサービスはキャッシュ構成ファイル内で定義され、自動的に起動されるように構成する必要があります。DISPOSINGイベントは、すべてのサービスが停止されて、すべてのリソースが解放される前に発生します。DISPOSINGイベントを処理するイベント・インターセプタは、サービスが停止される前に通知を受け取ります。ConfigurableCacheFactoryインスタンスのアクティブ化および破棄は1回のみ行うことができます。


注意:

ライフサイクル・イベントは、ConfigurableCacheFactory実装でライフサイクル・メソッドをコールするスレッドと同じスレッドによって、イベント・インターセプタにディスパッチされます。このスレッドは同期化されることがあります。イベント・インターセプタは、同じConfigurableCacheFactoryオブジェクトで、生成されたスレッドが同期化を行わないようにする必要があります。

表27-6は、ライフサイクル・イベント・タイプを示しています。

表27-6 ライフサイクル・イベント

イベント・タイプ 説明

ACTIVATED

ConfigurableCacheFactoryインスタンスがアクティブであることを示します。

DISPOSING

ConfigurableCacheFactoryインスタンスが破棄されようとしていることを示します。


27.2.5 フェデレーション・イベントの理解

フェデレーション・イベントは、フェデレーション・サービスによって実行されている操作を表す一連のイベントを表します。フェデレーション・イベントには、フェデレーテッド接続イベント(FederatedConnectionEvent)とフェデレーテッド変更イベント(FederatedChangeEvent)が含まれます。これらのイベントは、com.tangosol.net.events.federationパッケージ内で定義されます。

27.2.5.1 フェデレーテッド接続イベント

フェデレーテッド接続イベントは、フェデレーテッド・サービスの参加者間の通信を表します。


注意:

フェデレーテッド接続イベントは、イベントを発生させた同じスレッド上で発生します。これらのイベントを処理するインターセプタでは、ブロック操作を実行しないでください。

表27-7に、フェデレーテッド接続イベントのタイプを示します。

表27-7 フェデレーテッド接続イベント

イベント・タイプ 説明

CONNECTING

参加者との接続が開始されようとしていることを示します。

DISCONNECTED

参加者が接続されていないことを示します。

BACKLOG_EXCESSIVE

参加者がバックログされていることを示します。参加者がリモートの場合は、リモート参加者が処理できない量の作業があることを示します。参加者がローカルの場合は、この参加者が処理できない量の作業があることを示します。

BACKLOG_NORMAL

参加者がバックログされなくなったことを示します。

ERROR

変更をリモート参加者に適用している際にエラーが発生したか、接続の最大試行回数に達したことを示します。


27.2.5.2 フェデレーテッド変更イベント

フェデレーテッド変更イベントは、フェデレーションのローカル・クラスタ参加者で発生した変更のトランザクション・ビューを表します。トランザクションはパーティション用、つまり、単一のパーティションに属するすべての変更が単一のFederatedChangeEventオブジェクトで取得されます。


注意:

統合操作はフェデレーション変更イベントに含まれません。

フェデレーテッド変更イベントでは、キャッシュ・エントリに対する変更がコミットされる前に、その変更を許可するかどうかを決定することで、競合解決が可能になります。フェデレーテッド変更イベントの詳細は、『Oracle Coherenceの管理』を参照してください。

エントリを変更する際は、次の事項が当てはまります。

  • 同時更新を防止するために、イベントの処理中は各エントリに対してロックが保持されます。

  • 例外がスローされると、操作がコミットされなくなります。

表27-8に、フェデレーテッド変更イベントのタイプを示します。

表27-8 フェデレーテッド変更イベント

イベント・タイプ 説明

COMMITTING_LOCAL

エントリがローカル参加者のキャッシュに挿入されることを示します。

COMMITTING_REMOTE

他の参加者からのエントリがローカル参加者のキャッシュに挿入されることを示します。

REPLICATING

エントリがリモート参加者にレプリケートされることを示します。


27.3 ライブ・イベントの処理

アプリケーションは、イベント・インターセプタを使用してライブ・イベントを処理します。インターセプタは、どのイベントを受信するか、どのアクションを実行するのか(実行するアクションがある場合)を明示的に定義します。特定のキャッシュに対して、または特定のパーティション・サービスによって管理されるすべてのキャッシュに対して、任意の数のイベント・インターセプタを作成し、登録できます。同じイベント・タイプに対して登録されている複数のインターセプタは、自動的に連鎖され、1つのイベントのコンテキストで実行されます。

この項には次のトピックが含まれます:

27.3.1 イベント・インターセプタの作成

イベント・インターセプタを作成するには、EventInterceptorインタフェースを実装します。インタフェースはジェネリクスを使用して定義し、このインタフェースにより、汎用タイプのイベントをタイプ・パラメータとして指定してイベントをサブスクライブできるようになります。継承されたonEventメソッドは、イベントの受信時に必要な処理を実行する機能を提供します。EventInterceptor APIの詳細は、Oracle Coherence Java APIリファレンスを参照してください。次の例は、すべての転送イベントをサブスクライブするもので、例27-1からの抜粋です。

public class RedistributionInterceptor
   implements EventInterceptor<TransferEvent>

   public void onEvent(TransferEvent event)
   {
      ...

@Interceptor注釈を使用すると、イベントを特定のイベント・タイプにさらに制限でき、インターセプタのさらなる構成も可能です。次の例では、インターセプタ識別子を定義し、イベントを転送のDEPARTINGイベントのみに制限します。

@Interceptor(identifier = "redist", transferEvents = TransferEvent.Type.DEPARTING)
public class RedistributionInterceptor
   implements EventInterceptor<TransferEvent>

   public void onEvent(TransferEvent event)
   {
      ...

@Interceptor注釈には、次の属性が含まれます。

  • identifier - インターセプタの一意の識別子を指定します。識別子は、キャッシュ構成ファイルでインターセプタ・クラスを登録するときにオーバーライドできます。この属性はオプションです。この属性を省略した場合は、イベント・インフラストラクチャによって一意の名前が自動的に生成されます。

  • entryEvents - インターセプタがサブスクライブするエントリ・イベント・タイプの配列を指定します。

  • entryProcessorEvents - インターセプタがサブスクライブするエントリ・プロセッサ・イベント・タイプの配列を指定します。

  • transferEvents - インターセプタがサブスクライブする転送イベント・タイプの配列を指定します。

  • transactionEvents - インターセプタがサブスクライブするトランザクション・イベント・タイプの配列を指定します。

  • order - このインターセプタを、インターセプタの連鎖の前に配置するかどうかを指定します。「イベント・インターセプタの連鎖」を参照してください。有効な値はLOWHIGHです。HIGHの値は、そのインターセプタを、インターセプタの連鎖の前に配置することを示します。LOWの値は、順序付けのプリファレンスはないことを示します。デフォルト値はLOWです。この順序は、キャッシュ構成ファイルでインターセプタ・クラスを登録するときにオーバーライドできます。

次の例は、すべての転送イベント・タイプ(DEPARTINGARRIVEDの両方)をサブスクライブする基本的なイベント・インターセプタの実装を示しています。onEventメソッドは、単にパーティション・アクティビティを示すイベントを記録します。この例は、Coherenceの例の一部です。


注意:

イベント・インスタンスは不変であり、それらのライフサイクルは基礎となるシステムによって制御されます。イベント・クラスの参照は、onEvent()メソッドの複数の呼出しにわたって保持しないでください。

例27-1 イベント・インターセプタの実装例

package com.tangosol.examples.events;
import com.tangosol.net.CacheFactory;
import com.tangosol.net.events.EventInterceptor;
import com.tangosol.net.events.annotation.Interceptor;
import com.tangosol.net.events.partition.TransferEvent;

@Interceptor(identifier = "redist")
public class RedistributionInterceptor
   implements EventInterceptor<TransferEvent>
   {

   public void onEvent(TransferEvent event)
      {
      CacheFactory.log(String.format("Discovered event %s for partition-id %d
         from remote member %s\n", event.getType(), event.getPartitionId(),
         event.getRemoteMember()), CacheFactory.LOG_INFO);
      }
   }

27.3.2 イベントのスレッディングの理解

イベント・インターセプタは、キャッシュ操作に大きな影響を与えることがあるため、基礎となるスレッドをブロックしないように注意してください。そのようにしないとそれらに影響を与えます。イベント・インターセプタを作成する場合は、プリコミット・イベント・タイプとポストコミット・イベント・タイプの両方に対する影響を注意深く考慮する必要があります。


注意:

EventInterceptorインスタンスは再利用できますが、複数のスレッドが同時にディスパッチできるように、それらのインスタンスは不変であるかスレッド・セーフである必要があります。

プリコミット・イベント

プリコミット・イベント・タイプは、キャッシュにエントリがコミットされる前に、イベント・インターセプタにエントリを変更することを許可します。インターセプタは、同期的に処理されるため、実行時間の長い操作(データベース・アクセスなど)を実行しないでください。それによってキャッシュ操作がブロックされたり遅くなることがあります。外部リソースの呼出しは、キャッシュ操作がブロックされるのを防ぐために常にできるかぎり速く返す必要があります。

動的スレッド・プールはパーティション・サービスに対して自動的に有効化されます。スレッド・プールによって、キャッシュ操作を処理する追加のスレッドが作成され、プリコミット・イベントを処理するイベント・インターセプタによる全体的な影響が軽減されますが、ブロックされる可能性は依然として存在します。分散キャッシュ定義内の<thread-count-min>および<thread-count-max>要素を使用して、スレッド・プールのサイズを明示的に設定します。これらの要素の詳細は、「distributed-schemeのサブ要素」を参照してください。

ポストコミット・イベント

ポストコミット・イベントは、イベント・インターセプタによるエントリの変更を許可しません。そのイベントは、イベントの発生と同じ順序で発生し、インターセプタは非同期で処理されます。実行時間の長い操作を実行するイベント・インターセプタは、リクエストのバックログを発生させる場合があり、それによって最終的にパフォーマンスが低下することがあります。ベスト・プラクティスは、Java Executorサービスを使用してそのような操作を別のスレッドで実行することです。

27.3.3 イベント・インターセプタの登録

イベント・インターセプタは、キャッシュ構成ファイル内に登録されます。イベント・インターセプタは、特定のキャッシュまたはパーティション・サービスのいずれかに対して登録されます。特定のキャッシュに対して登録されたイベント・インターセプタは、そのキャッシュに関連するイベントのみを受信します。パーティション・サービスに対して登録されたイベント・インターセプタは、そのサービスによって管理されるキャッシュすべてのイベントを受信します。


注意:

サービスレベルのイベント(転送イベントやトランザクション・イベントなど)のイベント・インターセプタは、パーティション・サービスに対して登録する必要があり、特定のキャッシュに制限することはできません。

この項には次のトピックが含まれます:

27.3.3.1 特定のキャッシュに対するイベント・インターセプタの登録

特定のキャッシュに対してインターセプタを登録するには、任意の数の<interceptor>サブ要素を含む<interceptors>要素を<cache-mapping>要素内に含めます。各<interceptor>要素には、<instance>サブ要素を含め、EventInterceptorインタフェースを実装する完全修飾クラス名を指定する必要があります。<interceptor>要素の詳細なリファレンスについては、「interceptor」を参照してください。次の例では、MyInterceptorというイベント・インターセプタ・クラスを登録します。

<caching-scheme-mapping>
   <cache-mapping>
      <cache-name>example</cache-name>
      <scheme-name>distributed</scheme-name>
       <interceptors>
          <interceptor>
             <name>MyInterceptor</name>
             <instance>
                <class-name>
                   com.tangosol.examples.events.MyInterceptor
                </class-name>
             </instance>
          </interceptor>
      </interceptors>  
   </cache-mapping> 
</caching-scheme-mapping>

27.3.3.2 パーティション・サービスに対するイベント・インターセプタの登録

パーティション・サービスに対してインターセプタを登録するには、任意の数の<interceptor>サブ要素を含む<interceptors>要素を<distributed-scheme>要素内に含めます。各<interceptor>要素には、<instance>サブ要素を含め、EventInterceptorインタフェースを実装する完全修飾クラス名を指定する必要があります。<interceptor>要素の詳細なリファレンスについては、「interceptor」を参照してください。次の例では、例27-1で定義したRedistributionInterceptorクラスを登録します。

<distributed-scheme>
   <scheme-name>distributed</scheme-name>
   <service-name>PartitionedService1</service-name>
   <backing-map-scheme>
      <local-scheme/>
   </backing-map-scheme>
   <autostart>true</autostart>
   <interceptors>
      <interceptor>
         <name>MyInterceptor</name>
         <instance>
            <class-name>
               com.tangosol.examples.events.RedistributionInterceptor
            </class-name>
         </instance>
      </interceptor>
   </interceptors>  
</distributed-scheme>

27.3.3.3 キャッシュ構成ファクトリに対するイベント・インターセプタの登録

ConfigurableCacheFactoryインスタンスに対してインターセプタを登録するには、任意の数の<interceptor>サブ要素を含む<interceptors>要素を<cache-config>要素内に含めます。各<interceptor>要素には、<instance>サブ要素を含め、EventInterceptorインタフェースを実装する完全修飾クラス名を指定する必要があります。<interceptor>要素の詳細なリファレンスについては、「interceptor」を参照してください。次の例では、MyInterceptorというイベント・インターセプタ・クラスを登録します。

<cache-config>
   <interceptors>
      <interceptor>
         <name>MyInterceptor</name>
         <instance>
            <class-name>com.tangosol.examples.events.MyInterceptor</class-name>
         </instance>
      </interceptor>
   </interceptors>
   ...
</cache-config>

27.3.3.4 カスタム登録の使用

@Interceptor注釈および汎用タイプは、イベント・インフラストラクチャがイベント・インターセプタを適切なイベント・ディスパッチャに登録するために使用されます。このメカニズムは、ほとんどのユースケースでは問題ありません。ただし、高度なユースケースでは、イベント・インターセプタはEventDispatcherAwareInterceptorインタフェースを実装するように選択できるため、必要なイベント・ディスパッチャにイベント・インターセプタを手動で登録します。

introduceEventDispatcherメソッドには、インターセプタが登録されるイベント・ディスパッチャが含まれます。さらに必要に応じて、ディスパッチャのメソッドを使用して、インターセプタの追加および削除、特定のイベント・タイプの制限、およびインターセプタの構成を行います。次の例は、インターセプタを明示的に登録して、エントリのINSERTINGイベントをサブスクライブし、インターセプタが最初にコールされて通知されるように順序付けを構成するカスタム実装を示しています。

public void introduceEventDispatcher(String sIdentifier, EventDispatcher
   dispatcher)
   {
   dispatcher.addEventInterceptor(sIdentifier, this,
      new HashSet(Arrays.asList(EntryEvent.Type.INSERTING)), true);
   }

注意:

インターセプタが注釈を使用しないで構成されている場合、キャッシュ構成ファイルを使用してその構成をオーバーライドすることはできません。

インターセプタは、InterceptorRegistry APIを使用してプログラムによって登録することもできます。インターセプタを登録すると、現在登録されているイベント・ディスパッチャと将来のイベント・ディスパッチャのすべてにそのインターセプタが導入されます。インターセプタは、前述の例に示したようにintroduceEventDispatcherメソッドを使用して、ディスパッチャにバインドするかどうかを決定できます。

InterceptorRegistry APIはConfigurableCacheFactoryインタフェースから使用でき、getInterceptorRegistryメソッドを使用してコールします。このAPIは、宣言でインターセプタを登録するときのキャッシュ構成ファイルとあわせて使用できます。このAPIは、プログラムによってインターセプタを追加するためにカスタムDefaultCacheServer実装と一緒によく使用され、InvocationServiceインタフェースを使用する場合にインターセプタを選択によって登録するために使用されます。次の例では、インターセプタを登録します。

CacheFactory.getConfigurableCacheFactory().getInterceptorRegistry()
.registerEventInterceptor(new MyEventIntercepor());

27.3.3.5 イベント・インターセプタの登録のガイドライン

インターセプタは、同じサービスに対して複数の分散スキームで登録できます。また、分散スキームがスキーム参照を使用する場合、インターセプタ・クラスを継承できます。いずれの場合も、インターセプタ・クラスはサービスに登録されます。

ほとんどの場合、複数のインターセプタ・クラスを登録しても問題はありません。ただし、特定のサービスに対して同じインターセプタ・クラスおよび識別子名の重複が発生する可能性が高くなります。重複によって登録エラーが発生しないように、次のガイドラインに従ってください。

  • 識別子名が一意であるか、識別子名を定義しない場合は、1つの分散スキームや同じサービスの複数のスキームでインターセプタ・クラスを複数回複製できます。後者の場合は、イベント・インフラストラクチャによって一意の名前が自動的に生成されます。

  • 同じ識別子名のインターセプタ・クラスは(複製したものもそうでないものも)分散スキームで複数回登録することはできず、登録エラーが発生します。

  • スキーム参照によって継承されたインターセプタ・クラスは、参照の連鎖内で異なるサービス名ごとに1回ずつ登録されます。

27.3.4 イベント・インターセプタの連鎖

同じイベント・タイプに対して登録されている複数のイベント・インターセプタは、イベントのディスパッチを行うスレッドによってシリアルにコールされます。この方法でインターセプタを連鎖する機能により、カスタム・ロジックが連鎖内の他のインターセプタの結果に基づいて実行される複雑な処理シナリオが可能になります。連鎖ないの各イベント・インターセプタは次のことを実行できます。

  • イベントと関連付けられているデータを変更すること(許可されている場合)。たとえば、 INSERTINGUPDATINGREMOVINGなどのエントリ・イベントのプリコミット操作によってデータを変更できます。

  • 例外をスローしてプリコミット操作を拒否すること。

  • パーティションレベルのトランザクションに新しいエントリを参加させること。

  • 連鎖内の後続のイベント・インターセプタによる副作用の結果を監視すること。インターセプタ連鎖がプリコミット記憶域イベントと関連付けられている場合、結果を監視する機能により、処理を拒否するための2番目の機会が提供されます。

    後続のイベント・インターセプタの副作用の監視は、Event.nextInterceptorメソッドを使用して実行します。このメソッドが返されたとき、それは後続のイベント・インターセプタがすべて実行され、そのイベントに関連付けらている状態に対する変更をインターセプトできることを示します。Eventオブジェクトは、イベントの処理に関する状態を保持します。イベントは、連鎖内にイベント・インターセプタが存在するかぎり、各イベント・インターセプタのonEventメソッドをコールします。イベント・インターセプタ自体がEvent.nextInterceptorメソッドをコールする場合、連鎖内の次のイベント・インターセプタが起動されて実行されます。イベント・インターセプタが返されると、イベント自体が連鎖内の次のイベント・インターセプタのonEventメソッドをトリガーします。どちらの場合も、すべてのイベント・インターセプタが実行されますが、nextInterceptorメソッドをコールすることを選択すると、発生した副作用に基づいてアクションを実行するオプションがあります。

27.3.4.1 イベント・インターセプタの連鎖順序の指定

連鎖内のイベント・インターセプタは、登録された順序に基づいて実行されます。@Interceptor注釈のorder属性を使用して、インターセプタを連鎖の前に配置するかどうかを指定します。HIGHの値では、そのインターセプタが連鎖の前に配置されます。LOWの値は、デフォルト値であり、順序付けのプリファレンスはないことを示します。例:

@Interceptor(identifier = "MyInterceptor",
             entryEvents = {Type.INSERTING, Type.INSERTED}
             order = Order.HIGH)
public class MyInterceptor
        implements EventInterceptor<EntryEvent<?,?>>
...

順序は、キャッシュ構成ファイルでイベント・インターセプタを登録するときに宣言で指定することもでき、それによってイベント・インターセプタ・クラスで指定されているorder属性がオーバーライドされます。

キャッシュ構成ファイルでインターセプタの順序を指定するには、<interceptor>要素内に、HIGHまたはLOWに設定した<order>要素を含めます。例:

<interceptors>
   <interceptor>
      <name>MyInterceptor</name>
      <order>HIGH</order>
      <instance>
         <class-name>package.MyInterceptor</class-name>
      </instance>
   </interceptor>
   <interceptor>
      <name>MySecondInterceptor</name>
      <instance>
         <class-name>package.MySecondInterceptor</class-name>
      </instance>
   </interceptor>
</interceptors>