この演習では、EclipseでOracle Coherenceのキャッシュを作成および構成します。ここでは、Coherence APIのCacheStore、ContinuousQueryCache、IdentityExtractorおよびFilterの使用について取り上げます。
この演習では、次の3つのアイテムを作成します。
NamedCacheインスタンスを作成し、キャッシュ・エントリの挿入と取得が可能なJavaクラス。
キャッシュ名、キャッシュ・タイプおよびネーミング・パターンのマッピングを定義する、キャッシュ構成ファイル。
Oracle Databaseへの接続を作成し、表データの取得と格納が可能なJavaクラス。
データベース・キャッシュ。このクラスは、キャッシュ・エントリの追加、データベース・キャッシュの問合せ、エントリの取得を行います。
この章には次の項が含まれます:
Coherenceキャッシュは、データベースとクライアント・アプリケーションの仲介として機能するデータ・オブジェクトのコレクションです。データベース・データはキャッシュにロードされ、別のアプリケーションでの利用が可能になります。このようにしてCoherenceキャッシュはデータベースに対する負荷を軽減し、データベース・データへのアクセスを高速化します。
Coherenceキャッシュは、データベースの分離とデータ・レプリケーションによって、可用性を向上させます。データベースが利用可能であれば常に、キャッシュに対する変更をデータベースと同期できます。データベースまたはアプリケーション・サーバー・ノードが利用できない場合でも、Coherenceキャッシュで使用される遅延ロードと遅延書込み方式およびCoherenceが提供するフェイルオーバーとフェイルバックによって、データベース更新の信頼性が確保されます。
Coherenceキャッシュは、データ・オブジェクトに対してデータ変更操作を実行できるため、アプリケーション・サーバー・ノードのクラスタ間のみではなく、キャッシュ内のデータ・オブジェクト間にも分散処理を提供します。
Coherenceでは、イベントベースの処理も可能です。キャッシュ内のデータ・オブジェクトの状態はモニター可能で、Business Process Execution Language (BPEL)プロセスの開始など、他のプロセスによってアクションを起動できます。
Coherenceでは、様々なタイプのキャッシュがサポートされます。
クラスタ内のアプリケーション・サーバー・ノードのそれぞれにデータがレプリケートされる、レプリケート・キャッシュ。このタイプのキャッシュは、高速読取りアクセスが必要な場合にお薦めしますが、データをノードのそれぞれに書き込む必要があるため、書込み操作には向きません。レプリケート・キャッシュの短所は、すべてのノードにすべてのオブジェクトのコピーが保持されるため、大量のメモリーを必要とすることです。
データが複数のノード間で分散される(ロード・バランシング)、分散(またはパーティション)キャッシュ。フェイルオーバーはバックアップを使用して分散キャッシュに実装され、これもクラスタ・ノード間に分散されます。
Coherenceは、クラスタ・サービス、分散キャッシュ・サービスおよびレプリケート・キャッシュ・サービスなどのサービスを使用して実装されます。どちらのタイプのキャッシュを使用しても、アプリケーションでは同じAPIを使用してデータのアクセスと格納を行います。
キャッシュの構成には、キャッシュ構成デプロイメント・ディスクリプタが使用されます。キャッシュ構成ファイルのルート要素は、cache-configです。キャッシュ名と名前パターンは、サブ要素cache-mappingを使用して、caching-scheme-mapping要素内のキャッシュ・タイプにマップされます。キャッシュ・タイプはcaching-schemes要素で定義されます。表9-1は、Coherenceで一般的に使用されるキャッシュ・タイプの一部を示しています。
この項では、データをキャッシュに挿入して取得するアプリケーションの作成および実行方法を説明します。
Coherenceキャッシュを構成するJavaクラスを作成するには:
Eclipseで、プロジェクトを作成します。
EclipseでJPAパースペクティブを使用して、Interactionと呼ばれるJPAプロジェクトを作成します。第8章「JPAとCoherenceの併用」で作成したJPAConfigurationを選択します。
「JPA Facet」ページで、「Platform」フィールドに「EclipseLink 2.5.x」が表示されていることを確認します。ユーザー・ライブラリの下で「Coherence12.1.3」、「Oracle Database Driver」および「TopLink」が選択されていることを確認します。「Connection」フィールドで、「Connection」ドロップダウン・リストから「JPAに対するプロジェクトの構成」(XE_HR)で作成した接続を選択します。必要に応じて、「Connect」リンクをクリックしてOracle Databaseに接続します。(ここでは作成したデータベース接続が稼働中であると想定していることに注意してください。)「Add Driver Library to Build Path」を選択し、ドロップダウン・リストから「Oracle Database Driver Default」を選択します。「次へ」をクリックします。
「Coherence」ページで、「Coherence12.1.3」、「Oracle Database Driver」および「TopLink」が選択されていることを確認します。「Finish」をクリックします。
Coherenceキャッシュの作成に使用するJavaクラスCoherenceCacheを作成します。クラスにmainメソッドをインクルードします。クラス作成の詳細は、「Javaクラスの作成」を参照してください。
CoherenceCache Javaクラスでキャッシュを作成します。CacheFactoryクラスとNamedCacheインタフェースをインポートします。
import com.tangosol.net.CacheFactory; import com.tangosol.net.NamedCache;
CacheFactory.getCacheメソッドを使用して、キャッシュ(NamedCache)インスタンスを作成します。キャッシュ名VirtualCacheを使用します。これは分散キャッシュ・スキームにマップされます。
NamedCache cache = CacheFactory.getCache ( "VirtualCache");
NamedCacheは、クラスタ内のノード間で共有されるリソースを保持するjava.util.Mapインスタンスです。putメソッドを使用してキャッシュ・エントリを追加します。
cache.put (key, "Hello Cache");
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();
}
}
「Project Explorer」で、coherence-cache-config.xmlキャッシュ構成ファイルの名前をcache-config.xmlに変更します。Eclipseエディタでファイルを開きます。
キャッシュ構成ファイルで次のようにします。
caching-scheme-mapping要素内のcache-mapping要素を使用して、キャッシュ名とネーミング・パターンのマッピングを定義します。
キャッシュ名VirtualCacheをキャッシュ・タイプdistributed-eclipselinkにマップします。
EclipseLinkJPAサービスを使用して、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 http://xmlns.oracle.com/coherence/coherence-cache-config/1.2/coherence-cache-config.xsd">
<defaults>
<serializer system-property="tangosol.coherence.serializer"/>
<socket-provider system-property="tangosol.coherence.socketprovider"/>
</defaults>
<caching-scheme-mapping>
<cache-mapping>
<cache-name>VirtualCache</cache-name>
<scheme-name>distributed-eclipselink</scheme-name>
</cache-mapping>
</caching-scheme-mapping>
<caching-schemes>
<!--
Default Distributed caching scheme.
-->
<distributed-scheme>
<scheme-name>distributed-eclipselink</scheme-name>
<service-name>EclipseLinkJPA</service-name>
<backing-map-scheme>
<class-scheme>
<scheme-ref>default-backing-map</scheme-ref>
</class-scheme>
</backing-map-scheme>
<autostart>true</autostart>
</distributed-scheme>
<class-scheme>
<scheme-name>default-backing-map</scheme-name>
<class-name>com.tangosol.util.SafeHashMap</class-name>
</class-scheme>
</caching-schemes>
</cache-config>
アプリケーションの実行構成を作成して、ランタイムJavaオプションとしてキャッシュ構成ファイルを追加します。
「Project Explorer」でCoherenceCache.javaを右クリックして、「Run As」→「Run Configurations」を選択します。「Run Configurations」ダイアログ・ボックスで、「New launch configuration」アイコンをクリックします。
「Name」フィールドにCoherenceCacheServerと入力します。「Project」フィールドにInteractionが、「Main class」フィールドにcom.oracle.handson.CoherenceCacheが存在することを確認します。
「Coherence」タブで、キャッシュ構成ファイルへのパス(C:\home\oracle\workspace\Interaction\src\cache-config.xml)を入力します。Select the 「Enabled (cache server)」ボタンを選択します。「Cluster port」フィールドに3155などの一意の値を入力します。「Apply」をクリックします。
「Classpath」タブが図9-1のように表示されます。
相互作用プロジェクトのキャッシュ・サーバーの起動構成を作成するには:
「Interaction」プロジェクトを右クリックして、「Properties」を選択します。「Properties for Interact」ダイアログ・ボックスで、「Java Build Path」を選択します。「Order and Export」タブに、Interactionプロジェクト、JRE、Coherence12.1.3、TopLinkおよびOracle Database Driver Defaultライブラリが存在している必要があります。すべてが選択されていることを確認します。「Order and Export」タブが図9-2のように表示されます。
第8章「JPAとCoherenceの併用」で作成したJPAキャッシュ・サーバー起動構成(JPAServer)を編集します。
「Interaction」プロジェクトを右クリックして、「Run As」→「Run Configurations」を選択します。「Main」タブで、「Browse」をクリックして「Project Selection」ダイアログ・ボックスから「Interaction」プロジェクトを選択します。
「Coherence」タブの「General」タブで、構成ファイルの名前とパスをC:\home\oracle\workspace\Interaction\src\cache-config.xmlに置換します。
「Classpath」タブに「JPA (default classpath)」フォルダが表示されている場合は、それを削除します。「Add Project」をクリックして、「Interaction」プロジェクトを追加します。「Classpath」タブが図9-3のように表示されます。
「Common」タブの「Shared file」フィールドで、「Browse」をクリックして「Interaction」プロジェクトを選択します。「Apply」をクリックし、「Close」をクリックします。
キャッシュ作成アプリケーションCoherenceCache.javaを実行するには:
実行中のキャッシュ・サーバーがあれば停止します。詳細は、「キャッシュ・サーバーの停止」を参照してください。
JPAServerを実行して、キャッシュ・サーバーを起動します。
CoherenceアプリケーションCoherenceCache.javaを右クリックし、「Run As」→「Run Configurations」をクリックします。CoherenceCacheServer構成を選択して、「Run」をクリックします。Eclipseコンソール・ウィンドウに出力が表示されます。
操作構成がtangosol-coherence.xmlファイルから読み込まれます。このファイルは、Coherenceがクラスタリング、通信およびデータ管理サービスに使用するオペレーションおよびランタイム設定を指定します。
キャッシュ構成がcache-config.xmlファイルからロードされます。
新規クラスタが作成され、DistributedCacheサービスによってこのクラスタが結合されます。
CoherenceCache.javaプログラム、Hello Cacheの出力が表示されます。
例9-3 Coherenceキャッシュ・アプリケーションの出力
... 2013-12-20 11:41:53.821/0.930 Oracle Coherence GE 12.1.3.0.0 <Info> (thread=main, member=n/a): Loaded cache configuration from "file:/C:/home/oracle/workspace/Interaction/src/cache-config.xml" 2013-12-20 11:41:54.451/1.560 Oracle Coherence GE 12.1.3.0.0 <Info> (thread=main, member=n/a): Created cache factory com.tangosol.net.ExtensibleConfigurableCacheFactory 2013-12-20 11:41:55.672/2.781 Oracle Coherence GE 12.1.3.0.0 <D4> (thread=main, member=n/a):TCMP bound to /10.159.165.75:8090 using SystemDatagramSocketProvider2013-12-20 11:41:56.333/3.442 Oracle Coherence GE 12.1.3.0.0 <Info> (thread=Cluster, member=n/a): Failed to satisfy the variance: allowed=16, actual=20 ... 2013-12-20 11:41:57.384/4.493 Oracle Coherence GE 12.1.3.0.0 <Info> (thread=NameService:TcpAcceptor, member=2): TcpAcceptor now listening for connections on 10.159.165.75:8090.3 2013-12-20 11:41:57.744/4.853 Oracle Coherence GE 12.1.3.0.0 <D5> (thread=DistributedCache:EclipseLinkJPA, member=2): Service EclipseLinkJPA joined the cluster with senior service member 1Hello Cache
この項では、Oracle Databaseによってバッキングされるキャッシュを作成します。これは、Oracle Databaseキャッシュとも呼ばれます。
SQL*PlusおよびOracle Databaseを使用してOracle Databaseキャッシュを作成する手順は次のとおりです。システムにデータベースがインストールされている必要があります。
SQL*Plusを起動します。
「スタート」から「すべてのプログラム」→<Oracle Databaseホーム> (たとえば、「Oracle-OraDB12Home1」)→「Application Development」→「SQL Plus」とナビゲートします。
ユーザーhr、パスワードhrを使用して接続します。
connect hr/hr;
Oracle Database表を作成します。
テキスト・エディタを開き、次のSQLコードをコピーします。これを、/home/oracle/workspace/フォルダに、dbscript.sqlと名前を付けて保存します。
SQLスクリプトを実行します。
例9-5は、スクリプトからの出力を示しています。
例9-5 データベース表を作成するSQLスクリプトの実行
Copyright (c) 1982, 2013, Oracle. All rights reserved. Enter user-name: system Enter password: Last Successful login time: Thu Dec 19 2013 11:35:04 -08:00 Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options SQL> connect hr/hr; Connected. SQL> @/home/oracle/workspace/dbscript.sql Table created 1 row created 1 row created
データベースに接続し、表データを取得するJavaクラスを作成するには:
Eclipseで、「Interaction」プロジェクトにJava classのDBCacheStoreを作成します。詳細は、「Javaクラスの作成」を参照してください。
データベースに接続し、表データを取得するコードを作成します。
例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:orcl";
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();
}
}
前の手順でデータベース・キャッシュに作成したキャッシュ構成ファイル(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>
<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は、Coherenceで使用可能な読取り/書込みキャッシュのタイプを示しています。
Eclipseで、「Interaction」プロジェクトにデータベース・キャッシュ用Java classのDatabaseCacheを作成します。このクラスにはmainメソッドが格納されている必要があります。詳細は、「Javaクラスの作成」を参照してください。
クラス・ファイルで、キャッシュ・エントリの追加、データベース・キャッシュの問合せ、キャッシュ・エントリの取得を実行するコードを指定します。メソッドcreateCache()、addEntry()、retrieveEntry()、eraseEntry()およびqueryCache()を追加します。例9-8は、考えられる実装を示しています。
例9-8 DatabaseCacheクラス・ファイルの実装
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メソッドが起動されます。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メソッドを使用して実行されます。
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());
}
Coherenceでは、com.tangosol.net.cache.ContinuousQueryCacheクラスを使用した連続問合せがサポートされます。連続問合せは、連続的問合せキャッシュを使用して最新の状態に保持される問合せです。ContinuousQueryCacheでは、問合せの結果を変更する可能性があるイベントに対するイベント・リスナーを使用して、問合せの結果が更新されます。NamedCacheオブジェクトおよびLikeFilterオブジェクトを使用して、ContinuousQueryCacheオブジェクトを作成します。
ContinuousQueryCache queryCache = new ContinuousQueryCache(cache, filter);
entrySet()メソッドを使用して結果セットを作成します。
Set results = queryCache.entrySet(filter);
Oracle Databaseキャッシュ・アプリケーションを実行するには:
実行中のキャッシュ・サーバーがあれば停止します。詳細は、「キャッシュ・サーバーの停止」を参照してください。
キャッシュ・サーバー(JPAServer)を起動します。プロジェクトを右クリックして、「Run As」→「Run Configurations」を選択します。「Run Configurations」ダイアログ・ボックスで、JPACacheServerを選択してその構成を表示します。「Run」をクリックします。
DatabaseCacheプログラムの実行構成を作成します。
「Run Configurations」ダイアログ・ボックスで、「New launch configuration」アイコンをクリックします。
「Name」フィールドにDatabaseCacheClientと入力します。「Project」フィールドにInteractionが、「Main class」フィールドにcom.oracle.handson.DatabaseCacheが存在することを確認します。
「Coherence」タブの「Cache configuration descriptor」フィールドに、キャッシュ構成ファイルへのパスC:\home\oracle\workspace\Interaction\src\cache-config.xmlを入力します。「Local storage: Disabled (cache client)」」を選択します。「Cluster port」フィールドに3155などの一意の値を入力します。
「Classpath」タブを開きます。「Classpath」タブが図9-4のように表示されます。
「Apply」をクリックし、「Run」をクリックします。
例9-9は、予測される結果を示しています。
例9-9 DatabaseCacheプログラムの出力
...
Group{Address=224.12.1.0, Port=3155, TTL=4}
MasterMemberSet(
ThisMember=Member(Id=2, Timestamp=2013-12-20 12:28:41.013, Address=10.159.165.75:8090, MachineId=47251, Location=site:,machine:TPFAEFFL-LAP,process:1976, Role=OracleHandsonDatabaseCache)
OldestMember=Member(Id=1, Timestamp=2013-12-20 12:27:53.503, Address=10.159.165.75:8088, MachineId=47251, Location=site:,machine:TPFAEFFL-LAP,process:7320, Role=CoherenceServer)
ActualMemberSet=MemberSet(Size=2
Member(Id=1, Timestamp=2013-12-20 12:27:53.503, Address=10.159.165.75:8088, MachineId=47251, Location=site:,machine:TPFAEFFL-LAP,process:7320, Role=CoherenceServer)
Member(Id=2, Timestamp=2013-12-20 12:28:41.013, Address=10.159.165.75:8090, MachineId=47251, Location=site:,machine:TPFAEFFL-LAP,process:1976, Role=OracleHandsonDatabaseCache)
)
MemberId|ServiceVersion|ServiceJoined|MemberState
1|12.1.3|2013-12-20 12:27:53.503|JOINED,
2|12.1.3|2013-12-20 12:28:41.013|JOINED
RecycleMillis=1200000
RecycleSet=MemberSet(Size=0
)
)
TcpRing{Connections=[1]}
IpMonitor{Addresses=0}
2013-12-20 12:28:41.265/3.800 Oracle Coherence GE 12.1.3.0.0 <D5> (thread=Invocation:Management, member=2): Service Management joined the cluster with senior service member 1
2013-12-20 12:28:41.295/3.830 Oracle Coherence GE 12.1.3.0.0 <Info> (thread=main, member=2): Loaded Reporter configuration from "jar:file:/C:/Oracle/coherence/lib/coherence.jar!/reports/report-group.xml"
2013-12-20 12:28:41.715/4.250 Oracle Coherence GE 12.1.3.0.0 <Info> (thread=NameService:TcpAcceptor, member=2): TcpAcceptor now listening for connections on 10.159.165.75:8090.3
2013-12-20 12:28:42.086/4.621 Oracle Coherence GE 12.1.3.0.0 <D5> (thread=DistributedCache, member=2): Service DistributedCache joined the cluster with senior service member 1
Catalog ID: catalog5, Title: Tuning Database
Catalog ID: catalog4, Title: Tuning Coherence
Catalog ID: catalog3, Title: Tuning Grid Management
例9-10は、DatabaseCacheプログラムに対するキャッシュ・サーバーの応答を示しています。
例9-10 DatabaseCacheプログラムに対するキャッシュ・サーバーの応答
... Started DefaultCacheServer... 2013-12-20 12:28:41.208/50.536 Oracle Coherence GE 12.1.3.0.0 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2013-12-20 12:28:41.013, Address=10.159.165.75:8090, MachineId=47251, Location=site:,machine:TPFAEFFL-LAP,process:1976, Role=OracleHandsonDatabaseCache) joined Cluster with senior member 1 2013-12-20 12:28:41.275/50.603 Oracle Coherence GE 12.1.3.0.0 <D5> (thread=Invocation:Management, member=1): Member 2 joined Service Management with senior member 1 2013-12-20 12:28:42.296/51.624 Oracle Coherence GE 12.1.3.0.0 <D5> (thread=DistributedCache, member=1): Member 2 joined Service DistributedCache with senior member 1 2013-12-20 12:28:42.377/51.705 Oracle Coherence GE 12.1.3.0.0 <D5> (thread=Cluster, member=1): TcpRing disconnected from Member(Id=2, Timestamp=2013-12-20 12:28:41.013, Address=10.159.165.75:8090, MachineId=47251, Location=site:,machine:TPFAEFFL-LAP,process:1976, Role=OracleHandsonDatabaseCache) due to a peer departure; removing the member. 2013-12-20 12:28:42.377/51.705 Oracle Coherence GE 12.1.3.0.0 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2013-12-20 12:28:42.377, Address=10.159.165.75:8090, MachineId=47251, Location=site:,machine:TPFAEFFL-LAP,process:1976, Role=OracleHandsonDatabaseCache) left Cluster with senior member 1 2013-12-20 12:28:42.378/51.706 Oracle Coherence GE 12.1.3.0.0 <D5> (thread=DistributedCache, member=1): Member 2 left service DistributedCache with senior member 1 2013-12-20 12:28:42.378/51.706 Oracle Coherence GE 12.1.3.0.0 <D5> (thread=Invocation:Management, member=1): Member 2 left service Management with senior member 1
次のような例外が表示された場合:
java.lang.IllegalArgumentException: No scheme for cache: "cachename,
cache-config.xmlファイルを編集し、<cache-name>要素のDBBacked*を*に置換することによって、これらを解消できる場合があります。EclipseでDatabaseCacheアプリケーションを再実行します。例外が表示されないはずです。
ライトスルー・キャッシュを使用しているため、データベース表も更新されることに注意してください。SQLプロンプトから、次のコードを入力します。
select * from hr.catalog;
例9-11は、結果を示しています。
例9-11 SELECT文からの出力
... SQL> select * from hr.catalog; ID ------------------------- VALUE -------------------------------------------------------------------------------- catalog1 Tuning Undo Tablespace catalog2 Tuning Your View Objects catalog3 Tuning Grid Management ID ------------------------- VALUE -------------------------------------------------------------------------------- catalog4 Tuning Coherence catalog5 Tuning Database SQL>