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

前
 
次
 

26 トリガーを使用したマップ操作の制御

この章では、マップ・エントリに変更をコミットする前にマップ操作を検証、却下または変更するためのマップ・トリガーの使用方法について説明します。

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

26.1 マップ・トリガーの概要

マップ・トリガーは、Coherenceの標準機能を補助するもので、高度にカスタマイズされたキャッシュ管理システムを提供します。マップ・トリガーを使用すると、無効なトランザクションを回避したり、複雑なセキュリティ認証または複雑なビジネス・ルールを施行できます。また、透過的なイベント・ロギングや監査、データ変更の統計収集を行えます。トリガーのその他の用途には、キャッシュに対する操作を、アプリケーションの再デプロイメント時に発行されたものに制限することなどが挙げられます。

たとえば、NamedCacheの処理コードがあり、あるエントリの動作やコンテンツを、そのエントリがマップに挿入される前に変更するとします。マップ・トリガーを追加すると、既存のコードをすべて変更せずに、この変更を行うことができます。

マップ・トリガーは、アップグレード・プロセスの一環としても使用できます。マップ・トリガーを追加すると、挿入したエントリをキャッシュからキャッシュへ転用できます。

Coherenceキャッシュのマップ・トリガーは、データベースに適用されるトリガーに類似しています。これは、対応するマップ・エントリの保留中の変更(または削除)に応じて機能するMapTriggerインタフェースで表される機能エージェントです。保留中の変更は、MapTrigger.Entryインタフェースで表されます。このインタフェースは、InvocableMap.Entryインタフェースから継承され、基礎となるマップの値を取得、更新および削除するためのメソッドを提供します。

MapTriggerインタフェースには、マップ内の保留中の変更を検証、却下または変更する際に使用するprocessメソッドが備わっています。このメソッドは、基礎となるマップ・コンテンツの変更操作がコミットされる前にコールされます。このメソッドを実装すると、元の値と新しい値を分析することによって保留中の変更を評価し、次のいずれかの結果を得ることができます。

  • リクエストされた変更を別の値でオーバーライドします。

  • 元の値をリセットすることによって保留中の変更を元に戻します。

  • 基礎となるマップからエントリを削除します。

  • ランタイム例外をスローすることで保留中の変更を却下します。

  • 何もせずに、保留中の変更のコミットを許可します。

MapTrigger機能は通常、アプリケーション起動プロセスの一環として追加されます。MapTrigger APIで説明しているようにプログラムで追加できるほか、coherence-cache-config.xml構成ファイルでclass-factoryメカニズムを使用して構成することもできます。この場合、MapTriggerは、対応するキャッシュの最初のCacheFactory.getCache(...)コール時に登録されます。例26-1は、createMapTriggerメソッドが新しいMapTriggerListener(new MyCustomTrigger());を返すことを前提としています。

例26-1 MapTriggerListener構成の例

<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に登録する際に使用します。例26-2では、MapTriggerListenerを使用してPersonMapTriggerを名前付きキャッシュPeopleに登録します。

例26-2 MapTriggerListenerでMapTriggerを名前付きキャッシュに登録

NamedCache person = CacheFactory.getCache("People");
MapTrigger trigger = new PersonMapTrigger();
person.addMapListener(new MapTriggerListener(trigger));

これらのAPIはcom.tangosol.utilパッケージ内にあります。これらのAPIの詳細は、Oracle Coherence Java APIリファレンスを参照してください。

26.2 マップ・トリガーの例

例26-3のコードは、マップ・トリガーとそのコール方法を示しています。PersonMapTriggerクラスでは、processメソッドを実装して、マップに配置する前のエントリが変更されています。この場合、Personオブジェクトの姓の属性が大文字に変換されます。その後、オブジェクトはエントリに返されます。

例26-3 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-4MapTriggerは、PersonMapTriggerをコールします。新しいMapTriggerListenerは、PersonMapTriggerPeople NamedCacheに渡します。

例26-4 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");
        }
    }