26 トリガーを使用したマップ操作の制御
この章の構成は、次のとおりです。
- マップ・トリガーの概要
マップ・トリガーは、Coherenceの標準機能を補助するもので、高度にカスタマイズされたキャッシュ管理システムを提供します。 - マップ・トリガーの例
基本的な例に従って、マップ・トリガーの使用方法を理解します。
親トピック: データ・グリッド操作の実行
マップ・トリガーの概要
たとえば、NamedCache
の処理コードがあり、あるエントリの動作やコンテンツを、そのエントリがマップに挿入される前に変更するとします。マップ・トリガーを追加すると、既存のコードをすべて変更せずに、この変更を行うことができます。
マップ・トリガーは、アップグレード・プロセスの一環としても使用できます。マップ・トリガーを追加すると、挿入したエントリをキャッシュからキャッシュへ転用できます。
Coherenceキャッシュのマップ・トリガーは、データベースに適用されるトリガーに類似しています。これは、対応するマップ・エントリの保留中の変更(または削除)に応じて機能するMapTrigger
インタフェースで表される機能エージェントです。保留中の変更は、MapTrigger.Entry
インタフェースで表されます。このインタフェースは、InvocableMap.Entry
インタフェースから継承され、基礎となるマップの値を取得、更新および削除するためのメソッドを提供します。
MapTrigger
インタフェースには、マップ内の保留中の変更を検証、却下または変更する際に使用するprocess
メソッドが備わっています。このメソッドは、基礎となるマップ・コンテンツの変更操作がコミットされる前にコールされます。このメソッドを実装すると、元の値と新しい値を分析することによって保留中の変更を評価し、次のいずれかの結果を得ることができます。
-
リクエストされた変更を別の値でオーバーライドします。
-
元の値をリセットすることによって保留中の変更を元に戻します。
-
基礎となるマップからエントリを削除します。
-
ランタイム例外をスローすることで保留中の変更を却下します。
-
何もせずに、保留中の変更のコミットを許可します。
MapTrigger
機能は通常、アプリケーション起動プロセスの一環として追加されます。MapTrigger
APIで説明しているようにプログラムで追加できるほか、coherence-cache-config.xml
構成ファイルでclass-factory
メカニズムを使用して構成することもできます。この場合、MapTrigger
は、対応するキャッシュの最初のCacheFactory.getCache(
...)
コール時に登録されます。次の例は、createMapTrigger
メソッドが新しいMapTriggerListener(new MyCustomTrigger());
を返すことを前提としています。
<distributed-scheme> ... <listener> <class-scheme> <class-factory-name>package.MyFactory</class-factory-name> <method-name>createTriggerListener</method-name> <init-params> <init-param> <param-type>string</param-type> <param-value>{cache-name}</param-value> </init-param> </init-params> </class-scheme> </listener> </distributed-scheme>
Coherenceには、MapTrigger
.Entry
インタフェースとMapTrigger
インタフェースの他に、FilterTrigger
クラスとMapTriggerListener
クラスが用意されています。FilterTrigger
は、汎用のMapTrigger
実装であり、関連付けられているFilter
によって保留中の変更が却下された場合に、事前定義された処理を実行します。FilterTrigger
は、保留中の操作を却下するか、変更を無視してエントリの元の値をリストアするか、またはエントリ自体を基礎となるマップから削除します。
MapTriggerListener
は、特別な目的に使用するMapListener
実装であり、MapTrigger
を対応するNamedCache
に登録する際に使用します。次の例では、PersonMapTrigger
をPeople
名前付きキャッシュに登録します。
NamedCache person = CacheFactory.getCache("People"); MapTrigger trigger = new PersonMapTrigger(); person.addMapListener(new MapTriggerListener(trigger));
これらのAPIはcom.tangosol.util
パッケージ内にあります。
親トピック: トリガーを使用したマップ操作の制御
マップ・トリガーの例
PersonMapTrigger
クラスでは、process
メソッドを実装して、マップに配置する前のエントリが変更されています。この場合、Person
オブジェクトの姓の属性が大文字に変換されます。その後、オブジェクトはエントリに返されます。
例26-1 MapTriggerクラス
... public class PersonMapTrigger implements MapTrigger { public PersonMapTrigger() { } public void process(MapTrigger.Entry entry) { Person person = (Person) entry.getValue(); String sName = person.getLastName(); String sNameUC = sName.toUpperCase(); if (!sNameUC.equals(sName)) { person.setLastName(sNameUC); System.out.println("Changed last name of [" + sName + "] to [" + person.getLastName() + "]"); entry.setValue(person); } } // ---- hashCode() and equals() must be implemented public boolean equals(Object o) { return o != null && o.getClass() == this.getClass(); } public int hashCode() { return getClass().getName().hashCode(); } }
例26-2
のMapTriggerは、PersonMapTrigger
をコールします。新しいMapTriggerListener
は、PersonMapTrigger
をPeople
NamedCache
に渡します。
例26-2 MapTriggerコールと名前付きキャッシュへの引渡し
... public class MyFactory { /** * Instantiate a MapTriggerListener for a given NamedCache */ public static MapTriggerListener createTriggerListener(String sCacheName) { MapTrigger trigger; if ("People".equals(sCacheName)) { trigger = new PersonMapTrigger(); } else { throw IllegalArgumentException("Unknown cache name " + sCacheName); } System.out.println("Creating MapTrigger for cache " + sCacheName); return new MapTriggerListener(trigger); } public static void main(String[] args) { NamedCache cache = CacheFactory.getCache("People"); cache.addMapListener(createTriggerListener("People")); System.out.println("Installed MapTrigger into cache People"); } }
親トピック: トリガーを使用したマップ操作の制御