ヘッダーをスキップ
Oracle® Coherenceチュートリアル
リリース3.7.1
B65030-01
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次
索引へ移動
索引

前
 
次
 

9 キャッシュとデータベースの相互作用

この章では、EclipseでOracle Coherenceのキャッシュを作成し、構成します。この演習では、次の3つのアイテムを作成します。

この章では次の項について説明します。

9.1 概要

Coherenceキャッシュは、データベースとクライアント・アプリケーションの仲介として機能するデータ・オブジェクトのコレクションです。データベース・データはキャッシュにロードされ、別のアプリケーションでの利用が可能になります。このようにしてCoherenceキャッシュはデータベースに対する負荷を軽減し、データベース・データへのアクセスを高速化します。

Coherenceキャッシュは、データベースの分離とデータ・レプリケーションによって、可用性を向上させます。データベースが利用可能であれば常に、キャッシュに対する変更をデータベースと同期できます。データベース、またはアプリケーション・サーバー・ノードが利用できない場合でも、Coherenceキャッシュで使用される遅延ロードと遅延書込み方式およびOracle Coherenceが提供するフェイルオーバーとフェイルバックによって、データベース更新の信頼性が確保されます。

Coherenceキャッシュは、データ・オブジェクトに対してデータ変更操作を実行できるため、アプリケーション・サーバー・ノードのクラスタ間のみではなく、キャッシュ内のデータ・オブジェクト間にも分散処理を提供します。

Oracle Coherenceでは、イベントベースの処理も可能です。キャッシュ内のデータ・オブジェクトの状態は監視可能で、Business Process Execution Language(BPEL)プロセスの開始など、他のプロセスによってアクションを起動できます。

Oracle Coherenceでは、様々なタイプのキャッシュがサポートされます。

Oracle Coherenceは、クラスタ・サービス、分散キャッシュ・サービスおよびレプリケート・キャッシュ・サービスなどのサービスを使用して実装されます。どちらのタイプのキャッシュを使用しても、アプリケーションでは同じAPIを使用してデータのアクセスと格納を行います。

キャッシュの構成には、キャッシュ構成デプロイメント・ディスクリプタが使用されます。キャッシュ構成ファイルのルート要素は、cache-configです。キャッシュ名と名前パターンは、サブ要素cache-mappingを使用して、caching-scheme-mapping要素内のキャッシュ・タイプにマップされます。キャッシュ・タイプはcaching-schemes要素で定義されます。表9-1は、Coherenceで一般的に使用されるキャッシュ・タイプの一部を示しています。

表9-1 キャッシュ・タイプの説明

キャッシュ・タイプ 説明

分散スキーム

ノードのクラスタ間でデータが格納される分散キャッシュを定義。

レプリケート・スキーム

キャッシュ・エントリがすべてのクラスタ・ノードにレプリケートされるキャッシュを定義。

read-write-backing-mapスキーム

リレーショナル・データベースなどの永続的ストアのキャッシュを提供するマップを定義。

外部スキーム

ディスクなどの外部キャッシュを定義。

クラス・スキーム

java.util.Mapインタフェースの実装に必要な、カスタム・キャッシュ実装を定義。


9.2 キャッシュ・アプリケーションの作成

この項では、データをキャッシュに挿入して取得するアプリケーションの作成および実行方法を説明します。

  1. キャッシュを構成するアプリケーションの作成

  2. キャッシュ構成ファイルの作成

  3. プロジェクト・プロパティの構成

  4. キャッシュ・サーバー起動構成の作成

  5. キャッシュ作成アプリケーションの実行

9.2.1 キャッシュを構成するアプリケーションの作成

Coherenceキャッシュを構成するJavaクラスを作成するには:

  1. Eclipseで、プロジェクトを作成します。

    1. EclipseでJPAパースペクティブを使用して、Interactと呼ばれるJPAプロジェクトを作成します。前の章で作成したJPAConfigurationを選択します。

    2. 「Coherence」ページで、「Coherence37」および「EclipseLink2.1.2 - Helios」を選択します。

    3. 「JPA Facet」ページで、「Platform」フィールドに「EclipseLink 2.1.x」が表示されていることを確認します。「Connection」フィールドで、「Connection」ドロップダウン・リストから「JPAに対するプロジェクトの構成」(XE_HR)で作成した接続を選択します。「Connect」リンクをクリックして、Oracle XE Databaseに接続します。「Finish」をクリックします。(ここでは作成したデータベース接続が稼働中であると想定していることに注意してください)。

  2. Coherenceキャッシュの作成に使用するJavaクラスCoherenceCacheを作成します。クラスにmainメソッドをインクルードします。クラス作成の詳細は、「Javaクラスの作成」を参照してください。

    1. CoherenceCache Javaクラスでキャッシュを作成します。CacheFactoryクラスとNamedCacheインタフェースをインポートします。

      import com.tangosol.net.CacheFactory; 
      import com.tangosol.net.NamedCache;
      
    2. CacheFactory.getCacheメソッドを使用して、キャッシュ(NamedCache)インスタンスを作成します。キャッシュ名VirtualCacheを使用します。これは分散キャッシュ・スキームにマップされます。

      NamedCache cache = CacheFactory.getCache ( "VirtualCache");
      
    3. NamedCacheは、クラスタ内のノード間で共有されるリソースを保持するjava.util.Mapインスタンスです。putメソッドを使用してキャッシュ・エントリを追加します。

      cache.put (key, "Hello Cache");
      
    4. getメソッドを使用してキャッシュ・エントリを取得します。

      System.out.println((String)cache.get("hello"));
      

      例9-1は、考えられるCoherenceCacheクラスの実装を示しています。このコードは、EclipseでCoherenceCacheアプリケーションにコピーできます。

      例9-1 Coherenceキャッシュの実装

      package com.oracle.handson;
      
      import com.tangosol.net.CacheFactory; 
      import com.tangosol.net.NamedCache;
      
      public class CoherenceCache 
          {
          NamedCache cache;
          public CoherenceCache() 
          {
          }
          public void putCache()
              {
              cache = CacheFactory.getCache ( "VirtualCache"); 
              String key = "hello"; 
              cache.put (key, "Hello Cache"); 
              }
             
             public void retrieveCache()
                 {
                 System.out.println((String)cache.get("hello"));
                 }
             
              public static void main (String [] args) 
              {
              CoherenceCache cache = new CoherenceCache(); 
              cache.putCache();
              cache.retrieveCache();
              }
      }
      

9.2.2 キャッシュ構成ファイルの作成

キャッシュ構成デプロイメント・ディスクリプタとして、XMLドキュメントcache-config.xmlを作成します。このファイルをC:\home\oracle\workspaceフォルダに保存します。

キャッシュ構成ファイルで次のようにします。

  • caching-scheme-mapping要素内のcache-mapping要素を使用して、キャッシュ名とネーミング・パターンのマッピングを定義します。

  • キャッシュ名VirtualCacheをキャッシュ・タイプdefault-distributedにマップします。

  • DistributedCacheサービスを使用して、distributed-scheme要素で分散キャッシュ・スキームを定義します。

例9-2は、キャッシュ構成ファイルを示しています。この例のコンテンツをcache-config.xmlにコピーします。

例9-2 キャッシュ構成ファイル

<?xml version="1.0"?>
<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
              xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd">
    <caching-scheme-mapping>
        
        <cache-mapping>
            <cache-name>VirtualCache</cache-name>
            <scheme-name>default-distributed</scheme-name>
        </cache-mapping>
    </caching-scheme-mapping>
    <caching-schemes>
        <!--
        Default Distributed caching scheme.
        -->
        <distributed-scheme>
            <scheme-name>default-distributed</scheme-name>
            <service-name>DistributedCache</service-name>
            <backing-map-scheme>
                <class-scheme>
                    <scheme-ref>default-backing-map</scheme-ref>
                </class-scheme>
            </backing-map-scheme>
        </distributed-scheme>
         <class-scheme>
            <scheme-name>default-backing-map</scheme-name>
            <class-name>com.tangosol.util.SafeHashMap</class-name>
         </class-scheme>
  <autostart>true</autostart>
 </caching-schemes>
</cache-config>

9.2.3 プロジェクト・プロパティの構成

アプリケーションの実行構成を作成して、ランタイムJavaオプションとしてキャッシュ構成ファイルを追加します。

  1. Project Explorer」でCoherenceCache.javaを右クリックして、「Run As」→「Run Configurations」を選択します。「Run Configurations」ダイアログ・ボックスで、「New launch configuration」アイコンをクリックします。

  2. Name」フィールドにCoherenceCacheを入力します。「Project」フィールドにInteractが、「Main class」フィールドにcom.oracle.handson.CoherenceCacheが存在することを確認します。

  3. 「Coherence」タブで、キャッシュ構成ファイルへのパスC:\home\oracle\workspace\cache-config.xmlを入力します。Select the 「Enabled (cache server)」ボタンを選択します。「Cluster port」フィールドに3155などの一意の値を入力します。「Apply」をクリックします。

  4. Classpath」タブで、「Add External JARs」ボタンを使用して、coherence.jarファイルを「User Entries」に追加します。終了すると、「Classpath」タブが図9-1のように表示されます。

    図9-1 CoherenceCacheプログラムのクラスパス

    CoherenceCacheプログラムのクラスパス
    「図9-1 CoherenceCacheプログラムへのクラスパス」の説明

9.2.4 キャッシュ・サーバー起動構成の作成

相互作用プロジェクトのキャッシュ・サーバーの起動構成を作成するには:

  1. Interact」プロジェクトを右クリックして、「Properties」を選択します。「Properties for Interact」ダイアログ・ボックスで、「Java Build Path」を選択します。「Order and Export」タブに、Interactプロジェクト、JRE、EAR、Coherence37、EclipseLink 2.1.2 - HeliosおよびOracle Database 10g Driver Defaultライブラリが存在している必要があります。「Select All」をクリックします。「Order and Export」タブが図9-2のように表示されます。

    図9-2 Javaビルド・パスのライブラリの「Order and Export」タブ

    Javaビルド・パスのライブラリの順序付けとエクスポート
    「図9-2 Javaビルド・パスのライブラリの「Order and Export」タブ」の説明

  2. 第 8 章「JPAとCoherenceの併用」で作成したJPAキャッシュ・サーバー起動構成(JPACacheServer)を編集します。

  3. Interact」プロジェクトを右クリックして、「Run As」→「Run Configurations」を選択します。「Main」タブで、「Browse」をクリックして「Project Selection」ダイアログ・ボックスから「Interact」プロジェクトを選択します。

  4. Coherence」タブの「General」タブで、構成ファイルの名前とパスをC:\home\oracle\workspace\cache-config.xmlに置換します。

  5. Classpath」タブで、「JPA (default classpath)」フォルダを削除します。「Add Project」をクリックして、「Interact」プロジェクトを追加します。「Classpath」タブが図9-3のように表示されます。

    図9-3 相互作用プロジェクトキャッシュ・サーバーのクラスパス

    Interactプロジェクト・キャッシュ・サーバーの「Classpath」タブ
    「図9-3 相互作用プロジェクト・キャッシュ・サーバーのクラスパス」の説明

  6. Common」タブの「Shared file」フィールドで、「Browse」をクリックして「Interact」プロジェクトを選択します。「Apply」をクリックし、「Close」をクリックします。

9.2.5 キャッシュ作成アプリケーションの実行

キャッシュ作成アプリケーションCoherenceCache.javaを実行するには:

  1. 実行中のキャッシュ・サーバーがあれば停止します。詳細は、「キャッシュ・サーバーの停止」を参照してください。

  2. jpa-cache-server.cmdファイルを実行して、キャッシュ・サーバーを起動します。

  3. Oracle CoherenceアプリケーションCoherenceCache.javaを右クリックし、「Run As」→「Run Configurations」をクリックします。CoherenceCache構成を選択して、「Run」をクリックします。Eclipseコンソール・ウィンドウに出力が表示されます。

    • オペレーション構成がtangosol-coherence.xmlファイルから読み込まれます。このファイルは、Coherenceがクラスタ化、通信およびデータ管理サービスに使用するオペレーションおよびランタイム設定を指定します。

    • キャッシュ構成がcache-config.xmlファイルからロードされます。

    • 新規クラスタが作成され、DistributedCacheサービスによってこのクラスタが結合されます。

    • CoherenceCache.javaプログラム、Hello Cacheの出力が表示されます。

    例9-3 Coherenceキャッシュ・アプリケーションの出力

    2011-03-15 13:03:17.202/0.313 Oracle Coherence 3.7.0.0 <Info> (thread=main, member=n/a): Loaded operational configuration from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence.xml"
    2011-03-15 13:03:17.249/0.360 Oracle Coherence 3.7.0.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence-override-dev.xml"
    2011-03-15 13:03:17.280/0.391 Oracle Coherence 3.7.0.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "file:/C:/home/oracle/workspace/Interact/build/classes/tangosol-coherence-override.xml"
    2011-03-15 13:03:17.280/0.391 Oracle Coherence 3.7.0.0 <D5> (thread=main, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified
     
    Oracle Coherence Version 3.7.0.0 Build 22913
     Grid Edition: Development mode
    Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
     
    2011-03-15 13:03:17.436/0.547 Oracle Coherence GE 3.7.0.0 <Info> (thread=main, member=n/a): Loaded cache configuration from "file:/C:/home/oracle/workspace/cache-config.xml"
    2011-03-15 13:03:17.624/0.735 Oracle Coherence GE 3.7.0.0 <D4> (thread=main, member=n/a): TCMP bound to /130.35.99.213:8088 using SystemSocketProvider
    2011-03-15 13:03:21.202/4.313 Oracle Coherence GE 3.7.0.0 <Info> (thread=Cluster, member=n/a): Created a new cluster "cluster:0x96AB" with Member(Id=1, Timestamp=2011-03-15 13:03:17.639, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:2084, Role=OracleHandsonCoherenceCache, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1) UID=0x822363D50000012E733B6C87C2D51F98
    2011-03-15 13:03:21.217/4.328 Oracle Coherence GE 3.7.0.0 <Info> (thread=main, member=n/a): Started cluster Name=cluster:0x96AB
     
    Group{Address=224.3.7.0, Port=3155, TTL=4}
     
    MasterMemberSet
      (
      ThisMember=Member(Id=1, Timestamp=2011-03-15 13:03:17.639, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:2084, Role=OracleHandsonCoherenceCache)
      OldestMember=Member(Id=1, Timestamp=2011-03-15 13:03:17.639, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:2084, Role=OracleHandsonCoherenceCache)
      ActualMemberSet=MemberSet(Size=1, BitSetCount=2
        Member(Id=1, Timestamp=2011-03-15 13:03:17.639, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:2084, Role=OracleHandsonCoherenceCache)
        )
      RecycleMillis=1200000
      RecycleSet=MemberSet(Size=0, BitSetCount=0
        )
      )
     
    TcpRing{Connections=[]}
    IpMonitor{AddressListSize=0}
     
    2011-03-15 13:03:21.264/4.375 Oracle Coherence GE 3.7.0.0 <D5> (thread=Invocation:Management, member=1): Service Management joined the cluster with senior service member 1
    2011-03-15 13:03:21.405/4.516 Oracle Coherence GE 3.7.0.0 <D5> (thread=DistributedCache, member=1): Service DistributedCache joined the cluster with senior service member 1
    Hello Cache
    

9.3 データベース・キャッシュの作成

この項では、Oracle Databaseによってバッキングされるキャッシュを作成します。これは、Oracle Databaseキャッシュとも呼ばれます。

  1. Oracle Databaseキャッシュの作成

  2. カスタム・キャッシュ・ストアを定義するクラスの作成

  3. キャッシュ構成ファイルの変更

  4. データベース・キャッシュを構成するクラスの作成

  5. データベース・キャッシュ・アプリケーションの実行

9.3.1 Oracle Databaseキャッシュの作成

SQL*PlusおよびOracle Database Express Edition(Oracle XE)を使用してOracle Databaseキャッシュを作成する手順は次のとおりです。システムにデータベースがインストールされている必要があります。

  1. SQL*Plusを起動します。

    スタート」→「すべてのプログラム」→「Oracle Database Express Edition」→「SQLコマンドラインの実行」と移動します。

  2. ユーザーhr、パスワードhrを使用して接続します。

    connect hr/hr;
     
    
  3. Oracle Database表を作成します。

    テキスト・エディタを開き、次のSQLコードをコピーします。これを、/home/oracle/workspace/フォルダに、dbscript.sqlと名前を付けて保存します。

    例9-4 データベース表を作成するSQLスクリプト

    CREATE TABLE HR.CATALOG(id VARCHAR(25) PRIMARY KEY, value VARCHAR(96)); 
    INSERT INTO HR.CATALOG VALUES('catalog1', 'Tuning Undo Tablespace');
    INSERT INTO HR.CATALOG VALUES('catalog2', 'Tuning Your View Objects');
    
  4. SQLスクリプトを実行します。

    例9-5は、スクリプトからの出力を示しています。

    例9-5 データベース表を作成するSQLスクリプトの実行

    SQL*Plus: Release 10.2.0.1.0 - Production on Tue March 1 13:38:59 2011
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    
    SQL> connect hr/hr;
    Connected.
    SQL> @/home/oracle/workspace/dbscript.sql
    
    Table created
    
    1 row created
    
    1 row created
    

9.3.2 カスタム・キャッシュ・ストアを定義するクラスの作成

データベースに接続し、表データを取得するJavaクラスを作成するには:

  1. EclipseでJavaクラスDBCacheStoreを作成します。詳細は、「Javaクラスの作成」を参照してください。

  2. データベースに接続し、表データを取得するコードを作成します。

    例9-6は、考えられるDBCacheStoreクラスの実装を示しています。Eclipse IDEで、このコードをDBCacheStoreアプリケーションにコピーします。DBCacheStoreアプリケーションは、Java Database Connectivity(JDBC)を使用してOracle Databaseにアクセスしますが、HibernateやJava Data Objects(JDO)などの別のメカニズムを使用することもできます。

    例9-6 データベース・キャッシュ・ストアの実装

    package com.oracle.handson;
    
    import com.tangosol.net.cache.CacheStore;import com.tangosol.util.Base;
    
    import java.sql.DriverManager;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Collection;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    
    public class DBCacheStore
    
            extends Base
            implements CacheStore {
        
            protected Connection m_con;
            protected String m_sTableName;
            private static final String DB_DRIVER   = "oracle.jdbc.OracleDriver";
    
                
                private static final String DB_URL      = "jdbc:oracle:thin:@localhost:1521:XE";
                private static final String DB_USERNAME = "hr";
                private static final String DB_PASSWORD = "hr";
        
        public DBCacheStore(String sTableName)
            {
            m_sTableName = sTableName;
    
            configureConnection();        }
        protected void configureConnection()
            {
            try
                {
                Class.forName("oracle.jdbc.OracleDriver");
                m_con = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD);
                m_con.setAutoCommit(true);
                }
            catch (Exception e)
                {
                throw ensureRuntimeException(e, "Connection failed");
                }
            }
    
        public String getTableName()        {
            return m_sTableName;
            }
    
        public Connection getConnection()
            {
            return m_con;
            }
    
        public Object load(Object oKey)
            {
            Object     oValue = null;
            Connection con    = getConnection();
            String     sSQL   = "SELECT id, value FROM " + getTableName()
                        + " WHERE id = ?";
            try
                {
                PreparedStatement stmt = con.prepareStatement(sSQL);
    
                stmt.setString(1, String.valueOf(oKey));
                ResultSet rslt = stmt.executeQuery();
                if (rslt.next())
                    {
                    oValue = rslt.getString(2);
                    if (rslt.next())
                        {
                        throw new SQLException("Not a unique key: " + oKey);
                        }                }
                stmt.close();
                }
            catch (SQLException e)
                {
                throw ensureRuntimeException(e, "Load failed: key=" + oKey);
                }
            return oValue;
            }
    
          public void store(Object oKey, Object oValue)
            {
            Connection con     = getConnection();
            String     sTable  = getTableName();
            String     sSQL;
            
            if (load(oKey) != null)
                {
                
                sSQL = "UPDATE " + sTable + " SET value = ? where id = ?";
                }
            else
                {
                
                sSQL = "INSERT INTO " + sTable + " (value, id) VALUES (?,?)";
                }
            try
                {
                PreparedStatement stmt = con.prepareStatement(sSQL);
                int i = 0;
                stmt.setString(++i, String.valueOf(oValue));
                stmt.setString(++i, String.valueOf(oKey));
                stmt.executeUpdate();
                stmt.close();
                }
            catch (SQLException e)
                {
                throw ensureRuntimeException(e, "Store failed: key=" + oKey);
                }
            }
        public void erase(Object oKey)
            {
            Connection con  = getConnection();
            String     sSQL = "DELETE FROM " + getTableName() + " WHERE id=?";
            try
                {
                PreparedStatement stmt = con.prepareStatement(sSQL);
    
                stmt.setString(1, String.valueOf(oKey));
                stmt.executeUpdate();
                stmt.close();
                }
            catch (SQLException e)
                {
                throw ensureRuntimeException(e, "Erase failed: key=" + oKey);
                }
            }
        public void eraseAll(Collection colKeys)
            {
            throw new UnsupportedOperationException();
            }
    
        public Map loadAll(Collection colKeys)        {
            throw new UnsupportedOperationException();
            }
    
        public void storeAll(Map mapEntries)
            {
            throw new UnsupportedOperationException();
            }
       
        public Iterator keys()
            {
            Connection con  = getConnection();
            String     sSQL = "SELECT id FROM " + getTableName();
            List       list = new LinkedList();
            
            try
                {
                PreparedStatement stmt = con.prepareStatement(sSQL);
                ResultSet         rslt = stmt.executeQuery();
                while (rslt.next())
                    {
                    Object oKey = rslt.getString(1);
                    list.add(oKey);
                    }
                stmt.close();
                }
            catch (SQLException e)
                {
                throw ensureRuntimeException(e, "Iterator failed");
                }
    
            return list.iterator();
            }
        
        }
    

9.3.3 キャッシュ構成ファイルの変更

前の手順でデータベース・キャッシュに作成したキャッシュ構成ファイル(cache-config.xml)を変更します。キャッシュをデータベースに接続するには、com.tangosol.net.cache.CacheLoaderまたはcom.tangosol.net.cache.CacheStore のいずれかのインタフェースを実装するカスタム・クラスでcachestore-scheme要素を構成する必要があります。

Eclipseに既存のcache-config.xmlファイル内のコードを、例9-7のデータベース・キャッシュのキャッシュ構成コードに置換します。

例9-7 データベース・キャッシュの構成ファイル

<?xml version="1.0" encoding="UTF-8" ?>
<cache-config>
    <caching-scheme-mapping>
        
  <!-- 
    Caches with names that start with 'DBBacked' will be created 
    as distributed-db-backed.   
    -->
  <cache-mapping>
   <cache-name>DBBacked*</cache-name>
   <scheme-name>distributed-db-backed</scheme-name>
  </cache-mapping>
 </caching-scheme-mapping>
 <caching-schemes>
  <!-- 
    DB Backed Distributed caching scheme.
    -->
  <distributed-scheme>
   <scheme-name>distributed-db-backed</scheme-name>
   <service-name>DistributedCache</service-name>
   <backing-map-scheme>
    <read-write-backing-map-scheme>
     <internal-cache-scheme>
      <class-scheme>
       <class-name>com.tangosol.util.ObservableHashMap</class-name>
      </class-scheme>
     </internal-cache-scheme>
     <cachestore-scheme>  
      <class-scheme> 
       <class-name>com.oracle.handson.DBCacheStore</class-name> 
       <init-params>   
        <init-param> 
         <param-type>java.lang.String</param-type> 
         <param-value>CATALOG</param-value> 
        </init-param> 
       </init-params> 
      </class-scheme> 
     </cachestore-scheme>   
     <read-only>false</read-only>
     <!--
        To make this a write-through cache just change the value below to 0 (zero)
        -->
     <write-delay-seconds>0</write-delay-seconds>
    </read-write-backing-map-scheme>
   </backing-map-scheme>
   <listener/>
   <autostart>true</autostart>
  </distributed-scheme>
 </caching-schemes>
</cache-config>

キャッシュ構成ファイルで、次のように実行されています。

  • キャッシュ名パターンDBBacked*を定義しました。これは分散キャッシュ・スキームdistributed-db-backedにマップされています。

  • CacheStoreインタフェースを実装するクラスcoherence.DBCacheStoreを使用して、分散スキームでCacheStoreを指定しました。

  • DBCacheStoreクラスに、キャッシュのバック・エンドにあるデータベース表のinitパラメータを指定しました。表の名前はinit-param要素で指定されています。DBCacheStoreクラスは、キャッシュ・エントリの読取り、書込みなどのデータベース操作を実行します。

  • バッキング・マップとして、read-write-backing-map-schemeを指定しました。このスキームは、バッキング・マップを定義し、永続ストアにサイズ制限のあるキャッシュを提供します。ここで、write-delay-secondsパラメータを0に設定すると、ライトスルー・メカニズムが指定されます。

    表9-2は、Oracle Coherenceで使用可能な読取り/書込みキャッシュのタイプを示しています。

表9-2 Coherenceによってサポートされる読取り/書込みキャッシュのタイプ

読取り/書込みキャッシュのタイプ アクション

リードスルー

要求されアプリケーションでの利用が可能になると、キャッシュ・エントリがデータベースからキャッシュに読み取られる。

ライトスルー

キャッシュ・エントリの更新が遅延なくデータベースと同期する。

リフレッシュアヘッド

キャッシュ・エントリが定期的にリフレッシュされる。

ライトビハインド

キャッシュ構成ファイルのwrite-delay-seconds要素で指定された遅延の後、キャッシュ・エントリへの更新が非同期でデータベースに書き込まれる。


9.3.4 データベース・キャッシュを構成するクラスの作成

Eclipseで、データベース・キャッシュのJavaクラスDatabaseCacheを作成します。このクラスにはmainメソッドが格納されている必要があります。詳細は、「Javaクラスの作成」を参照してください。

クラス・ファイルで、キャッシュ・エントリの追加、データベース・キャッシュの問合せ、キャッシュ・エントリの取得を実行するコードを指定します。メソッドcreateCache()addEntry()retrieveEntry()eraseEntry()およびqueryCache()を追加します。例9-8は、考えられる実装を示しています。

例9-8 データベース・キャッシュ・クラス・ファイルの実装

package com.oracle.handson;

import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
import com.tangosol.net.cache.ContinuousQueryCache;
import com.tangosol.util.Filter;
import com.tangosol.util.extractor.IdentityExtractor;
import com.tangosol.util.filter.LikeFilter;

import java.util.HashSet;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class DatabaseCache {
    NamedCache cache;
    public DatabaseCache() {
    }

    public void createCache() 
         {
         cache = CacheFactory.getCache("DBBackedCache");
         }

    public void addEntry() 
        {
        cache.put(new String("catalog3"), new String("Tuning Grid Management"));
        cache.put(new String("catalog4"), new String("Tuning Coherence"));
        cache.put(new String("catalog5"), new String("Tuning Database"));
        }

    public void retrieveEntry() 
        {
        System.out.println((String) cache.get( "catalog3"));
        }

    public void eraseEntry() 
       {
       cache.remove(new String("catalog3"));
       }

    public void queryCache() 
       {
       Filter filter = new LikeFilter(IdentityExtractor.INSTANCE, "Tuning%", '\\', true);
       HashSet hashSet=new HashSet();
       hashSet.add(new String("catalog3"));
       hashSet.add(new String("catalog4"));
       hashSet.add(new String("catalog5"));

       Map map=cache.getAll(hashSet);
       Set results = cache.entrySet(filter);
        
           for (Iterator i = results.iterator(); i.hasNext();)
               {
               Map.Entry e = (Map.Entry) i.next();
               System.out.println("Catalog ID: "+e.getKey() + ", Title: "+e.getValue());
               }
        }
    
    public static void main(String[] args) 
       {
       DatabaseCache databaseCache = new DatabaseCache();
       databaseCache.createCache();
       databaseCache.addEntry();
       databaseCache.queryCache();
       }
}

データベース・キャッシュ・クラス・ファイルの次の機能に注意してください。

  • NamedCacheオブジェクトは、createCacheメソッド内のCacheFactoryクラスのgetCacheメソッドを使用して作成されます。

    NamedCache cache = CacheFactory.getCache("DBBackedCache");
    
  • DBBackedCacheは、キャッシュ・パターンDBBacked*と一致するため、cache-config.xmlファイルの分散キャッシュ・スキームdistributed-db-backedにマップされます。NamedCacheオブジェクトのput()メソッドを使用してキャッシュ・エントリを追加します。

    cache.put(new String("catalog3"), new String("Tuning Grid Management"));
    
  • ライトスルー・メカニズムが使用されるため、新しいキャッシュ・エントリはデータベースと同期し、CATALOG表に新規行が追加されます。メソッドcreateCacheおよびaddEntryを除くすべてのメソッドをコメント・アウトします。

  • putメソッドが起動されると、DBCacheStoreクラスで、JDBCを使用してデータベース表CATALOGに新規のキャッシュ・エントリをマップするstoreメソッドが起動されます。Oracle Coherenceアプリケーションからの出力が「ログ」ウィンドウに表示され、新しいキャッシュ・エントリが追加されます。出力には、操作構成デプロイメント・ディスクリプタがロードされたこと、新しいクラスタが作成されたことおよびDistributedCacheサービスがクラスタに結合されたことが示されます。

  • 新規のキャッシュ・エントリは、NamedCacheオブジェクトのremoveメソッドを使用して削除できます。

    cache.remove(new String("catalog3"));
    
  • キャッシュ・エントリのバルク・アップロードは、putAllメソッドを使用して実行されます。

  • NamedCacheオブジェクトのgetメソッドを使用してキャッシュ・エントリが取得されます。たとえば、ID catalog1のキャッシュ・エントリを取得する方法は次のとおりです。

    System.out.println((String) cache.get("catalog1"));
    
  • get()メソッドが起動されると、DBCacheStoreクラスでJDBCを使用してデータベース表データを取得するloadメソッドが起動されます。

  • バルク取得は、NamedCacheオブジェクトのgetAllメソッドを使用して実行されます。

  • Oracle Coherenceでは、フィルタを使用して、検索基準に基づくキャッシュ・エントリの検索がサポートされます。Coherenceのフィルタは、com.tangosol.util.filterパッケージで提供されています。Oracle Coherence Enterprise EditionおよびGrid Editionでは、Coherenceキャッシュに索引を追加してパフォーマンスを向上できます。キャッシュ・エントリを指定パターンと照合するLikeFilterフィルタを使用してデータベース・キャッシュにクエリーを実行します。データベース・キャッシュへの問合せを実行するには、問合せの前にキャッシュ・エントリを作成し、フィルタを使用した問合せの実行を可能にするには、事前にget()またはgetAll()メソッドを使用してキャッシュ・エントリをキャッシュに取得しておく必要があります。したがって、getAll()メソッドを使用すると、データベース・データの取得とキャッシュ・エントリのコレクションの作成を実行できます。

    HashSet hashSet=new HashSet(); 
    hashSet.add(new String("catalog1")); 
    hashSet.add(new String("catalog2")); 
    hashSet.add(new String("catalog3")); 
    Map map=cache.getAll(hashSet);
    
  • Tuningで開始するキャッシュ・エントリ検索のためのフィルタLikeFilterを作成します。

    Filter filter = new LikeFilter(IdentityExtractor.INSTANCE, "Tuning%", '\\', true);
    
  • LikeFilterフィルタを指定し、entrySet()メソッドを使用してデータベース・キャッシュへの問合せを実行します。

    Set results = cache.entrySet(filter);
    
  • 問合せの結果に対して反復処理を行います。取得されたキャッシュ・エントリのキーと値を表示します。

    for (Iterator i = results.iterator(); i.hasNext();) 
       {
       Map.Entry e = (Map.Entry) i.next();
       System.out.println("Catalog ID: "+e.getKey() + ", Title: "+e.getValue());
       }
    
  • Oracle Coherenceでは、com.tangosol.net.cache.ContinuousQueryCacheクラスを使用した連続問合せがサポートされます。連続問合せは、連続的問合せキャッシュを使用して最新の状態に保持される問合せです。ContinuousQueryCacheでは、問合せの結果を変更する可能性があるイベントに対するイベント・リスナーを使用して、問合せの結果が更新されます。NamedCacheオブジェクトおよびLikeFilterオブジェクトを使用して、ContinuousQueryCacheオブジェクトを作成します。

    ContinuousQueryCache queryCache = new ContinuousQueryCache(cache, filter );
    
  • entrySet()メソッドを使用して結果セットを作成します。

    Set results = queryCache.entrySet(filter);
    

9.3.5 データベース・キャッシュ・アプリケーションの実行

Oracle Databaseキャッシュ・アプリケーションを実行するには:

  1. 実行中のキャッシュ・サーバーがあれば停止します。詳細は、「キャッシュ・サーバーの停止」を参照してください。

  2. キャッシュ・サーバー(JPACacheServer)を起動します。プロジェクトを右クリックして、「Run As」→「Run Configurations」を選択します。「Run Configurations」ダイアログ・ボックスで、JPACacheServerを選択してその構成を表示します。「Run」をクリックします。

  3. DatabaseCacheプログラムの実行構成を作成します。

    1. Run Configurations」ダイアログ・ボックスで、「New launch configuration」アイコンをクリックします。

    2. Name」フィールドにDatabaseCacheを入力します。「Project」フィールドにInteractが、「Main class」フィールドにcom.oracle.handson.DatabaseCacheが存在することを確認します。

    3. Coherence」タブの「Cache configuration descriptor」フィールドに、キャッシュ構成ファイルへのパス C:\home\oracle\workspace\cache-config.xmlを入力します。「Local storage: Disabled (cache client)」を選択します。「Cluster port」フィールドに3155などの一意の値を入力します。

    4. Classpath」タブで、「Add External JARs」ボタンを使用して、coherence.jarファイルを「User Entries」に追加します。「Classpath」タブが図9-4のように表示されます。

      図9-4 DatabaseCacheプログラムへのクラスパス

      DatabaseCacheプログラムへのクラスパス
      「図9-4 DatabaseCacheプログラムへのクラスパス」の説明

    5. Apply」をクリックし、「Run」をクリックします。

      例9-9は、予測される結果を示しています。

      例9-9 DatabaseCacheプログラムの出力

      ...
      2011-03-15 13:47:59.374/0.329 Oracle Coherence 3.7.0.0 <Info> (thread=main, member=n/a): Loaded operational configuration from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence.xml"
      2011-03-15 13:47:59.420/0.375 Oracle Coherence 3.7.0.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence-override-dev.xml"
      2011-03-15 13:47:59.452/0.407 Oracle Coherence 3.7.0.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "file:/C:/home/oracle/workspace/Interact/build/classes/tangosol-coherence-override.xml"
      2011-03-15 13:47:59.467/0.422 Oracle Coherence 3.7.0.0 <D5> (thread=main, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified
       
      Oracle Coherence Version 3.7.0.0 Build 22913
       Grid Edition: Development mode
      Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
       
      2011-03-15 13:47:59.624/0.579 Oracle Coherence GE 3.7.0.0 <Info> (thread=main, member=n/a): Loaded cache configuration from "file:/C:/home/oracle/workspace/cache-config.xml"
      2011-03-15 13:47:59.811/0.766 Oracle Coherence GE 3.7.0.0 <D4> (thread=main, member=n/a): TCMP bound to /130.35.99.213:8090 using SystemSocketProvider
      2011-03-15 13:48:00.327/1.282 Oracle Coherence GE 3.7.0.0 <Info> (thread=Cluster, member=n/a): This Member(Id=2, Timestamp=2011-03-15 13:48:00.17, Address=130.35.99.213:8090, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:5076, Role=OracleHandsonDatabaseCache, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1) joined cluster "cluster:0x96AB" with senior Member(Id=1, Timestamp=2011-03-15 13:33:58.514, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:3524, Role=CoherenceServer, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1)
      2011-03-15 13:48:00.342/1.297 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=n/a): Member 1 joined Service Cluster with senior member 1
      2011-03-15 13:48:00.342/1.297 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=n/a): Member 1 joined Service Management with senior member 1
      2011-03-15 13:48:00.342/1.297 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=n/a): Member 1 joined Service DistributedCache with senior member 1
      2011-03-15 13:48:00.342/1.297 Oracle Coherence GE 3.7.0.0 <Info> (thread=main, member=n/a): Started cluster Name=cluster:0x96AB
       
      Group{Address=224.3.7.0, Port=3155, TTL=4}
       
      MasterMemberSet
        (
        ThisMember=Member(Id=2, Timestamp=2011-03-15 13:48:00.17, Address=130.35.99.213:8090, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:5076, Role=OracleHandsonDatabaseCache)
        OldestMember=Member(Id=1, Timestamp=2011-03-15 13:33:58.514, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:3524, Role=CoherenceServer)
        ActualMemberSet=MemberSet(Size=2, BitSetCount=2
          Member(Id=1, Timestamp=2011-03-15 13:33:58.514, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:3524, Role=CoherenceServer)
          Member(Id=2, Timestamp=2011-03-15 13:48:00.17, Address=130.35.99.213:8090, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:5076, Role=OracleHandsonDatabaseCache)
          )
        RecycleMillis=1200000
        RecycleSet=MemberSet(Size=0, BitSetCount=0
          )
        )
       
      TcpRing{Connections=[1]}
      IpMonitor{AddressListSize=0}
       
      2011-03-15 13:48:00.436/1.391 Oracle Coherence GE 3.7.0.0 <D5> (thread=Invocation:Management, member=2): Service Management joined the cluster with senior service member 1
      2011-03-15 13:48:00.514/1.469 Oracle Coherence GE 3.7.0.0 <D5> (thread=DistributedCache, member=2): Service DistributedCache joined the cluster with senior service member 1
      Catalog ID: catalog3, Title: Tuning Grid Management
      Catalog ID: catalog4, Title: Tuning Coherence
      Catalog ID: catalog5, Title: Tuning Database
      

      例9-10は、DatabaseCacheプログラムに対するキャッシュ・サーバーの応答を示しています。

      例9-10 DatabaseCacheプログラムに対するキャッシュ・サーバーの応答

      ...
      Started DefaultCacheServer...
       
      2011-03-15 13:48:00.327/843.922 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2011-03-15 13:48:00.17, Address=130.35.99.213:8090, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:5076, Role=OracleHandsonDatabaseCache) joined Cluster with senior member 1
      2011-03-15 13:48:00.436/844.031 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member 2 joined Service Management with senior member 1
      2011-03-15 13:48:00.545/844.156 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member 2 joined Service DistributedCache with senior member 1
      2011-03-15 13:48:02.842/846.437 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): TcpRing disconnected from Member(Id=2, Timestamp=2011-03-15 13:48:00.17, Address=130.35.99.213:8090, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:5076, Role=OracleHandsonDatabaseCache) due to a peer departure; removing the member.
      2011-03-15 13:48:02.842/846.437 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member 2 left service Management with senior member 1
      2011-03-15 13:48:02.842/846.437 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member 2 left service DistributedCache with senior member 1
      2011-03-15 13:48:02.842/846.437 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2011-03-15 13:48:02.842, Address=130.35.99.213:8090, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:5076, Role=OracleHandsonDatabaseCache) left Cluster with senior member 1
      

      次のような例外が表示された場合:

      java.lang.IllegalArgumentException: No scheme for cache: "cachename, 
      

      cache-config.xmlファイルを編集し、<cache-name>要素のDBBacked**に置換することによって、これらを解消できる場合があります。EclipseでDatabaseCacheアプリケーションを再実行します。例外が表示されないはずです。

  4. ライトスルー・キャッシュを使用しているため、データベース表も更新されることに注意してください。SQLプロンプトから、次のコードを入力します。

    select * from hr.catalog;
    

    例9-11は、結果を示しています。

    例9-11 SELECT文からの出力

    ....
    select * from hr.catalog;
    ID
    -------------------------
    VALUE--------------------------------------------------------------------------------
    catalog3
    Tuning Grid Management
    
    catalog4
    Tuning Coherence
    
    catalog5
    Tuning Database
    
    ID
    -------------------------
    VALUE--------------------------------------------------------------------------------
    catalog1
    Tuning Undo Tablespace
    
    catalog2
    Tuning Your View Objects