ヘッダーをスキップ
Oracle Coherence開発者ガイド
リリース3.5
B56039-01
  目次
目次

戻る
戻る
 
次へ
次へ
 

4 トリガーを使用したマップ操作の管理

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

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

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

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

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

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

例4-1 coherence-cache-config.xmlファイルでのMapTriggerListenerの作成

<cache-config>
  ...
    <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>
  ...
</cache-config>

MapTrigger.EntryインタフェースやMapTriggerインタフェースに加えて、Oracle CoherenceではFilterTriggerクラスおよびMapTriggerListenerクラスも提供されています。FilterTriggerは、汎用のMapTrigger実装であり、関連付けられているFilterによって保留中の変更が却下された場合に、事前定義された処理を実行します。FilterTriggerは、保留中の操作を却下するか、変更を無視してエントリの元の値をリストアするか、またはエントリ自体を基礎となるマップから削除します。

MapTriggerListenerは、特別な目的に使用するMapListener実装であり、MapTriggerを対応するNamedCacheに登録する際に使用します。例4-2では、MapTriggerListenerを使用してPersonMapTriggerPeople名前付きキャッシュに登録します。

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

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

これらのAPIは、com.tangosol.utilパッケージ内にあります。これらのAPIの詳細は、JavadocのMapTriggerMapTrigger.EntryFilterTriggerおよびMapTriggerListenerに関するページを参照してください。

マップ・トリガーの例

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

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

例4-4MapTriggerは、PersonMapTriggerをコールします。新しいMapTriggerListenerは、PersonMapTriggerPeople NamedCacheに渡します。

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