外部トランザクション・マネージャー

通常、eXtreme Scale トランザクションは、Session.begin メソッドで開始し、Session.commit メソッドで終了します。 しかし、ObjectGrid が組み込まれている場合、外部トランザクション・コーディネーターがトランザクションの開始と終了を行うことができます。 この場合、begin メソッドまたは commit メソッドを呼び出す必要はありません。

外部トランザクションの調整

TransactionCallback プラグインは、eXtreme Scale セッションと外部トランザクションを関連づける isExternalTransactionActive(Session session) メソッドにより拡張されます。このメソッドのヘッダーは次のとおりです。

public synchronized boolean isExternalTransactionActive(Session session)

例えば、eXtreme Scale をセットアップして WebSphere® Application Server および WebSphere Extended Deployment と統合することができます。

また、eXtreme Scale に は、WebSphere という名前の組み込みプラグインもあります (トランザクションのライフサイクル・イベントの管理のためのプラグイン)。これは、WebSphere Application Server 環境向けにプラグインをビルドする方法を記述しますが、他のフレームワーク用にプラグインを適応させることもできます。

このシームレスな統合の鍵となるのが、WebSphere Application Server バージョン 5.x およびバージョン 6.x の ExtendedJTATransaction API の利用です。ただし、WebSphere Application Server バージョン 6.0.2 をご使用の場合は、このメソッドをサポートするために APAR PK07848 を適用する必要があります。次のサンプル・コードを使用して、ObjectGrid セッションを WebSphere Application Server トランザクション ID と関連付けます。
/**
* This method is required to associate an objectGrid session with a WebSphere 
* Application Server transaction ID.
*/
Map/**/ localIdToSession;
public synchronized boolean isExternalTransactionActive(Session session)
{
    // remember that this localid means this session is saved for later.
    localIdToSession.put(new Integer(jta.getLocalId()), session);
    return true;
}

外部トランザクションの検索

TransactionCallback プラグインを使用するために、外部トランザクション・サービス・オブジェクトを検索しなければならない場合があります。WebSphere Application Server サーバーでは、次の例に示すように、名前空間から ExtendedJTATransaction オブジェクトを検索します。
public J2EETransactionCallback() {
    super();
    localIdToSession = new HashMap();
    String lookupName="java:comp/websphere/ExtendedJTATransaction";
    try
    {
        InitialContext ic = new InitialContext();
        jta = (ExtendedJTATransaction)ic.lookup(lookupName);
        jta.registerSynchronizationCallback(this);
    }
    catch(NotSupportedException e)
    {
        throw new RuntimeException("Cannot register jta callback", e);
    }
    catch(NamingException e){
        throw new RuntimeException("Cannot get transaction object");
    }
}

他の製品の場合は、トランザクション・サービス・オブジェクトを検索するために同じような方法を使用することができます。

外部コールバックによりコミットを制御する

TransactionCallback プラグインは、eXtreme Scale セッションをコミットまたはロールバックするために、外部信号を受信する必要があります。この外部信号を受信するには、外部トランザクション・サービスからのコールバックを使用します。外部コールバック・インターフェースを実装し、それを外部トランザクション・サービスで登録する必要があります。例えば、WebSphere Application Server の場合、次の例に示すように、SynchronizationCallback インターフェースを実装します。
public class J2EETransactionCallback implements 
	com.ibm.websphere.objectgrid.plugins.TransactionCallback, SynchronizationCallback {
   public J2EETransactionCallback() {
      super();
      String lookupName="java:comp/websphere/ExtendedJTATransaction";
      localIdToSession = new HashMap();
      try {
         InitialContext ic = new InitialContext();
         jta = (ExtendedJTATransaction)ic.lookup(lookupName);
         jta.registerSynchronizationCallback(this);
      } catch(NotSupportedException e) {
         throw new RuntimeException("Cannot register jta callback", e);
      }
      catch(NamingException e) {
         throw new RuntimeException("Cannot get transaction object");
      }
   }

   public synchronized void afterCompletion(int localId, byte[] arg1,boolean didCommit) {
      Integer lid = new Integer(localId);
      // find the Session for the localId
      Session session = (Session)localIdToSession.get(lid);
      if(session != null) {
         	try {
            // if WebSphere Application Server is committed when 
            // hardening the transaction to backingMap.
            // We already did a flush in beforeCompletion
            if(didCommit) {
               session.commit();
            } else {
               // otherwise rollback
               session.rollback();
            }
         } catch(NoActiveTransactionException e) {
            // impossible in theory
         } catch(TransactionException e) {
            // given that we already did a flush, this should not fail
         } finally {
            // always clear the session from the mapping map.
            localIdToSession.remove(lid);
         }
      }
   }

   public synchronized void beforeCompletion(int localId, byte[] arg1) {
      Session session = (Session)localIdToSession.get(new Integer(localId));
      if(session != null) {
         try {
            session.flush();
         } catch(TransactionException e) {
            // WebSphere Application Server  does not formally define 
            // a way to signal the
            // transaction has failed so do this
            throw new RuntimeException("Cache flush failed", e);
         }
      }
   }
}

TransactionCallback プラグインでの eXtreme Scale API の使用

TransactionCallback プラグイン は、eXtreme Scale 内での自動コミットを使用不可にします。eXtreme Scale の通常の使用パターンは以下のとおりです。
Session ogSession = ...;
ObjectMap myMap = ogSession.getMap("MyMap");
ogSession.begin();
MyObject v = myMap.get("key");
v.setAttribute("newValue");
myMap.update("key", v);
ogSession.commit();
この TransactionCallback プラグインが使用されている場合、 eXtreme Scale は、コンテナー管理対象トランザクションが存在するときにアプリケーションが eXtreme Scale を使用すると想定します。前出のコードの断片は、この環境で次のコードに変わります。
public void myMethod() {
   UserTransaction tx = ...;
   tx.begin();
   Session ogSession = ...;
   ObjectMap myMap = ogSession.getMap("MyMap");
   yObject v = myMap.get("key");
   v.setAttribute("newValue");
   myMap.update("key", v);
   tx.commit();
}

myMethod メソッドは、Web アプリケーションのシナリオに類似しています。アプリケーションは通常の UserTransaction インターフェースを使用してトランザクションを開始、コミット、およびロールバックします。 eXtreme Scale はコンテナー・トランザクションなどを自動的に開始およびコミットします。メソッドが TX_REQUIRES 属性を使用する Enterprise JavaBeans (EJB) メソッドの場合は、UserTransaction 参照および UserTransaction 呼び出しを除去してトランザクションを開始、コミットすると、メソッドが同じように動作します。この場合、コンテナーがトランザクションの開始と終了を行います。