ヘッダーをスキップ
Oracle® Coherenceクライアント・ガイド
リリース3.6.1
B61370-02
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

24 .NETクライアントに対するトランザクションの実行

この章では、トランザクション・フレームワークAPIを使用して、.NETクライアント使用時にトランザクション内でキャッシュ操作が実行されるようにする手順について説明します。この手順では、トランザクションAPIの詳細な使用方法は説明しません。トランザクションAPIの使用方法の詳細は、『Oracle Coherence開発者ガイド』のトランザクション・フレームワークAPIの使用方法に関する項を参照してください。

この章は、トランザクションの実行に必要な次の各項で構成されています。

入力プロセッサ内でのトランザクションAPIの使用方法

.NETクライアントは、トランザクション・フレームワークAPIを利用することによって、トランザクション内でキャッシュ操作を実行します。トランザクションAPIは、.NETでネイティブではサポートされていないため、入力プロセッサ内で使用する必要があります。入力プロセッサはJavaでクラスタ上に実装され、入力プロセッサのスタブ・クラスは.NETでクライアント上に実装されます。いずれのクラスでも、POFを利用して、JavaとC#の間でシリアライズを行います。

例24-1は、トランザクションAPIを使用してトランザクション内で単純なupdate操作を実行する入力プロセッサを示しています。実行時には、Coherenceプロキシ・サーバーのクラスパス上にクラスを配置する必要があります。

例24-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を使用する際の詳細は、第20章「.NETクライアントの統合オブジェクトの構築」を参照してください。

例24-2は、例24-1で作成したトランザクション入力プロセッサの入力プロセッサ・スタブ・クラスを示しています。

例24-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を使用する必要があります。次の例は、例24-1で作成したMyTxProcessorクラスと、例24-2で作成したクライアント・スタブ・クラスのそれぞれの登録方法を示しています。

クラスタ側のPOF構成:

<?xml version="1.0"?><!DOCTYPE pof-config SYSTEM "pof-config.dtd"><pof-config>
   <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>

クライアント側のPOF構成:

<?xml version="1.0"?><!DOCTYPE pof-config SYSTEM "pof-config.dtd"><pof-config>
   <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という名前のトランザクション・キャッシュを作成します。これは、例24-1で入力プロセッサによって使用されていたキャッシュ名です。この構成には、リモート・クライアントから入力プロセッサを実行する際に必要なプロキシ・スキームと分散キャッシュ・スキームも含まれています。プロキシは、ポート9099localhostでクライアントのTCP/IP接続を受け入れるように構成します。Coherence*Extend使用時にクラスタ側のキャッシュを構成する方法の詳細は、第3章「Coherence*Extendの設定」を参照してください。

<cache-config>
   <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>
         <task-timeout>0</task-timeout>
         <thread-count>7</thread-count>
         <autostart>true</autostart>
         <high-units>15M</high-units>
      </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>
         <thread-count>5</thread-count>
         <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>

クライアント側のリモート・キャッシュの構成

クラスタのプロキシに接続してトランザクション入力プロセッサを実行するには、リモート・クライアントにリモート・キャッシュが必要です。リモート・キャッシュは、クライアント側のキャッシュ構成ファイルで定義します。クライアント側のキャッシュを構成する方法の詳細は、第3章「Coherence*Extendの設定」を参照してください。

次の例では、リモート・キャッシュをポート9099localhostに配置されているプロキシに接続するように構成します。また、リモート・キャッシュの名前(dist-example)はトランザクション入力プロセッサの開始時に使用されるクラスタ側のキャッシュの名前と一致している必要があります。

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

.NETクライアントからのトランザクション入力プロセッサの使用方法

クライアントで入力プロセッサのスタブ・クラスを起動する方法は、入力プロセッサを起動する方法と同じです。ただし、実行時に、クラスタ側の入力プロセッサがクラスタ上で起動されます。起動がJavaクラスに委任されたことは、クライアント側では認識されません。次の例は、入力プロセッサのスタブ・クラスを使用して、結果的に例24-1で作成したトランザクション入力プロセッサを起動するクライアントを示しています。

INamedCache cache  = CacheFactory.GetCache("dist-example");
object      result = cache.Invoke( "AnyKey", new MyTxProcessor());

Console.Out.WriteLine("Result of extend tx execution: " + result );