この章では、トランザクション・フレームワークAPIを使用して、.NETクライアント使用時にトランザクション内でキャッシュ操作が実行されるようにする手順について説明します。この手順では、トランザクションAPIの詳細な使用方法は説明しません。トランザクションAPIの使用方法の詳細は、『Oracle Coherenceでのアプリケーションの開発』のトランザクション・フレームワークAPIに関する項を参照してください。
この章は、トランザクションの実行に必要な次の各項で構成されています。
.NETクライアントは、トランザクション・フレームワークAPIを利用することによって、トランザクション内でキャッシュ操作を実行します。トランザクションAPIは、.NETでネイティブではサポートされていないため、入力プロセッサ内で使用する必要があります。入力プロセッサはJavaでクラスタ上に実装され、入力プロセッサのスタブ・クラスはC#でクライアント上に実装されます。いずれのクラスでも、POFを使用して、JavaとC#の間でシリアライズを行います。
例21-1は、トランザクションAPIを使用してトランザクション内で単純なupdate
操作を実行する入力プロセッサを示しています。実行時には、Coherenceプロキシ・サーバーのクラスパス上にクラスを配置する必要があります。
例21-1 Extendクライアント・トランザクション用の入力プロセッサ
package coherence.tests; import com.tangosol.coherence.transaction.Connection; import com.tangosol.coherence.transaction.ConnectionFactory; import com.tangosol.coherence.transaction.DefaultConnectionFactory; import com.tangosol.coherence.transaction.OptimisticNamedCache; import com.tangosol.coherence.transaction.exception.PredicateFailedException; import com.tangosol.coherence.transaction.exception.RollbackException; import com.tangosol.coherence.transaction.exception.UnableToAcquireLockException; import com.tangosol.util.Filter; import com.tangosol.util.InvocableMap; import com.tangosol.util.extractor.IdentityExtractor; import com.tangosol.util.filter.EqualsFilter; import com.tangosol.util.processor.AbstractProcessor; public class MyTxProcessor extends AbstractProcessor implements PortableObject { public Object process(InvocableMap.Entry entry) { // obtain a connection and transaction cache ConnectionFactory connFactory = new DefaultConnectionFactory(); Connection conn = connFactory.createConnection("TransactionalCache"); OptimisticNamedCache cache = conn.getNamedCache("MyTxCache"); conn.setAutoCommit(false); // get a value for an existing entry String sValue = (String) cache.get("existingEntry"); // create predicate filter Filter predicate = new EqualsFilter(IdentityExtractor.INSTANCE, sValue); try { // update the previously obtained value cache.update("existingEntry", "newValue", predicate); } catch (PredicateFailedException e) { // value was updated after it was read conn.rollback(); return false; } catch (UnableToAcquireLockException e) { // row is being updated by another tranaction conn.rollback(); return false; } try { conn.commit(); } catch (RollbackException e) { // transaction was rolled back return false; } return true; } public void readExternal(PofReader in) throws IOException { } public void writeExternal(PofWriter out) throws IOException { } }
入力プロセッサのスタブ・クラスを使用すると、クライアントはクラスタ上でトランザクション入力プロセッサを利用できます。スタブ・クラスはC#で実装され、POFを使用してシリアライズを行います。POFを使用することにより、C#とJavaの間で入力プロセッサをシリアライズできます。入力プロセッサのスタブ・クラスにはトランザクション・ロジックは必要ありません。これはトランザクション入力プロセッサのスケルトンです。.NETでPOFを使用する際の詳細は、第17章「.NETクライアントの統合オブジェクトの構築」を参照してください。
例21-2は、例21-1で作成したトランザクション入力プロセッサの入力プロセッサ・スタブ・クラスを示しています。
例21-2 トランザクション入力プロセッサの.NETスタブ・クラス
using Tangosol.IO.Pof; using Tangosol.Net.Cache; using Tangosol.Util.Processor; namespace Coherence.Tests{ public class MyTxProcessor : AbstractProcessor, IPortableObject { public MyTxProcessor() { } public override object Process(IInvocableCacheEntry entry) { return null; } public void ReadExternal(IPofReader reader) { } public void WriteExternal(IPofWriter writer) { } } }
カスタム・ユーザー・タイプは、Javaトランザクション入力プロセッサに関してはクラスタ側のPOF構成ファイルで、クライアント・スタブに関してはクライアント側のPOF構成ファイルで登録する必要があります。両方の登録で、同じタイプIDを使用する必要があります。次の例は、例21-1で作成したMyTxProcessor
クラスと、例21-2で作成したクライアント・スタブ・クラスのそれぞれの登録方法を示しています。
クラスタ側のPOF構成:
<?xml version="1.0"?> <pof-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.oracle.com/coherence/coherence-pof-config" xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-pof-config coherence-pof-config.xsd"> <user-type-list> <include>coherence-pof-config.xml</include> <include>txn-pof-config.xml</include> <user-type> <type-id>1599</type-id> <class-name>coherence.tests.MyTxProcessor</class-name> </user-type> </user-type-list> </pof-config>
クライアント側のPOF構成:
<?xml version="1.0"?> <pof-config xmlns="http://schemas.tangosol.com/pof" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.tangosol.com/pof assembly://Coherence/Tangosol.Config/pof-config.xsd"> <user-type-list> <include>coherence-pof-config.xml</include> <user-type> <type-id>1599</type-id> <class-name>Coherence.Tests.MyTxProcessor</class-name> </user-type> </user-type-list> </pof-config>
トランザクションを実行するには、クラスタ側のキャッシュ構成ファイルでトランザクション・キャッシュを定義する必要があります。トランザクション・キャッシュは、トランザクション・フレームワークでトランザクション保証を行うために使用します。トランザクション・キャッシュの詳細は、『Oracle Coherenceでのアプリケーションの開発』のトランザクション・キャッシュの定義に関する項を参照してください。
次の例では、MyTxCache
という名前のトランザクション・キャッシュを作成します。これは、例21-1で入力プロセッサによって使用されていたキャッシュ名です。この構成には、リモート・クライアントから入力プロセッサを実行する際に必要なプロキシ・スキームと分散キャッシュ・スキームも含まれています。プロキシは、ポート9099
のlocalhost
でクライアントのTCP/IP接続を受け入れるように構成します。Coherence*Extend使用時にクラスタ側のキャッシュを構成する方法の詳細は、第4章「Coherence*Extendの設定」を参照してください。
<?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>MyTxCache</cache-name> <scheme-name>example-transactional</scheme-name> </cache-mapping> <cache-mapping> <cache-name>dist-example</cache-name> <scheme-name>example-distributed</scheme-name> </cache-mapping> </caching-scheme-mapping> <caching-schemes> <transactional-scheme> <scheme-name>example-transactional</scheme-name> <service-name>TransactionalCache</service-name> <thread-count>7</thread-count> <high-units>15M</high-units> <task-timeout>0</task-timeout> <autostart>true</autostart> </transactional-scheme> <distributed-scheme> <scheme-name>example-distributed</scheme-name> <service-name>DistributedCache</service-name> <backing-map-scheme> <local-scheme/> </backing-map-scheme> <autostart>true</autostart> </distributed-scheme> <proxy-scheme> <service-name>ExtendTcpProxyService</service-name> <acceptor-config> <tcp-acceptor> <local-address> <address>localhost</address> <port>9099</port> </local-address> </tcp-acceptor> </acceptor-config> <autostart>true</autostart> </proxy-scheme> </caching-schemes> </cache-config>
クラスタのプロキシに接続してトランザクション入力プロセッサを実行するには、リモート・クライアントにリモート・キャッシュが必要です。リモート・キャッシュは、クライアント側のキャッシュ構成ファイルで定義します。クライアント側のキャッシュを構成する方法の詳細は、第4章「Coherence*Extendの設定」を参照してください。
次の例では、リモート・キャッシュをポート9099
のlocalhost
に配置されているプロキシに接続するように構成します。また、リモート・キャッシュの名前(dist-example
)はトランザクション入力プロセッサの開始時に使用されるクラスタ側のキャッシュの名前と一致している必要があります。
<?xml version='1.0'?> <cache-config xmlns="http://schemas.tangosol.com/cache" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.tangosol.com/cache assembly://Coherence/Tangosol.Config/cache-config.xsd"> <caching-scheme-mapping> <cache-mapping> <cache-name>dist-example</cache-name> <scheme-name>extend</scheme-name> </cache-mapping> </caching-scheme-mapping> <caching-schemes> <remote-cache-scheme> <scheme-name>extend</scheme-name> <service-name>ExtendTcpCacheService</service-name> <initiator-config> <tcp-initiator> <remote-addresses> <socket-address> <address>localhost</address> <port>9099</port> </socket-address> </remote-addresses> <connect-timeout>30s</connect-timeout> </tcp-initiator> <outgoing-message-handler> <request-timeout>30s</request-timeout> </outgoing-message-handler> </initiator-config> </remote-cache-scheme> </caching-schemes> </cache-config>
クライアントで入力プロセッサのスタブ・クラスを起動する方法は、入力プロセッサを起動する方法と同じです。ただし、実行時に、クラスタ側の入力プロセッサがクラスタ上で起動されます。起動がJavaクラスに委任されたことは、クライアント側では認識されません。次の例は、入力プロセッサのスタブ・クラスを使用して、結果的に例21-1で作成したトランザクション入力プロセッサを起動するクライアントを示しています。
INamedCache cache = CacheFactory.GetCache("dist-example"); object result = cache.Invoke( "AnyKey", new MyTxProcessor()); Console.Out.WriteLine("Result of extend transaction execution: " + result );