4.3.3 トランザクションの開始、コミット、およびロールバック

Joltでは、トランザクションはJoltTransactionクラスのオブジェクトとして表されます。トランザクションは、トランザクション・オブジェクトがインスタンス化されると開始されます。次に示すように、トランザクション・オブジェクトの作成時には、タイムアウト値とJoltSessionオブジェクトのパラメータが設定されます。

trans = new JoltTransaction(timeout, session)

Joltでは、トランザクションに関与するすべてのサービスに対して明示的なトランザクション・モデルを使用します。トランザクション・サービスを呼び出すには、JoltTransactionオブジェクトがパラメータとして必要です。また、サービスとトランザクションが同じセッションに属していることも必要です。Joltでは、同じセッションにバインドされていないサービスとトランザクションを使用することはできません

「Joltのファンド転送の例(SimXfer.java)」のサンプル・コードは、Joltクラス・ライブラリの使い方を示しています。ここでは、JoltSessionAttributes、JoltSession、JoltRemoteService、およびJoltTransactionクラスを使用しています。

例では、ユーザー定義された2つのOracle Tuxedoサービス(WITHDRAWALとDEPOSIT)をバインドして、TRANSFERトランザクションを擬似的に実行します。WITHDRAWAL操作が失敗した場合は、ロールバックが実行されます。それ以外の場合はDEPOSITが実行され、commitによりトランザクションが完了します。

「Joltのファンド転送の例(SimXfer.java)」のサンプル・コードに示すトランザクション・プロセスのプログラミング・ステップは、以下のとおりです。

  1. hostnameportnumberなどの接続属性をJoltSessionAttributeオブジェクトに設定します。

    コード・リストで次の行を参照してください。

    sattr = new JoltSessionAttributes();
  2. sattr.checkAuthenticationLevel()を使用すると、サーバーへのログオンに必要なセキュリティ・レベルをアプリケーション側で決定できます。

    コード・リストで次の行を参照してください。

    switch (sattr.checkAuthenticationLevel())
  3. JoltSessionオブジェクトをインスタンス化してログオンします。

    コード・リストで次の行を参照してください。

    session = new JoltSession (sattr, userName, userRole,
    userPassword, appPassword);

    この例では、SessionExceptionエラーを明示的に取得しません。

  4. すべてのJoltRemoteService呼出しでは、サービスの指定とJoltSession()から返されたセッション・キーが必要です。コード・リストで次の行を参照してください。
    withdrawal = new JoltRemoteService(“WITHDRAWAL”, session);
    deposit = new JoltRemoteService(“DEPOSIT”, session);

    これらの呼出しは、Oracle Tuxedoサービス・メタデータ・リポジトリに格納されているWITHDRAWALおよびDEPOSITのサービス定義を、withdrawalオブジェクトおよびdepositオブジェクトにそれぞれバインドします。WITHDRAWALおよびDEPOSITサービスがメタデータ・リポジトリで定義されていないと、ServiceExceptionがスローされます。この例では、ServiceExceptionエラーを明示的に取得しません。

  5. サービス定義が返されると、アプリケーション固有のフィールド(アカウント番号を示すACCOUNT_IDや引出し額を示すSAMOUNTなど)に自動的に値が設定されます。

    コード・リストで次の行を参照してください。

    withdrawal.addInt(“ACCOUNT_ID”, 100000);
    withdrawal.addString(“SAMOUNT”, “100.00”);

    add*()メソッドでは、IllegalAccessErrorまたはNoSuchFieldError例外がスローされる場合があります。

  6. JoltTransaction呼出しでは、指定した時間内にトランザクションが完了しない場合のタイムアウト値を指定できます。

    コード・リストで次の行を参照してください。

    trans = new JoltTransaction(5,session);
  7. withdrawalサービスの定義が自動的に設定された後でwithdrawal.call(trans)メソッドを呼び出すと、withdrawalサービスが呼び出されます。

    コード・リストで次の行を参照してください。

    withdrawal.call(trans);
  8. 失敗したWITHDRAWALはロールバックできます。

    コード・リストで次の行を参照してください。

    trans.rollback();
  9. または、いったんDEPOSITが実行されると、すべてのトランザクションがコミットされます。コード・リストで次の行を参照してください。

    deposit.call(trans);

    trans.commit();

次のリストに、Joltクラスを使用して資金の振替えを行うための単純なアプリケーションの例を示します。

Joltの資金振替えの例(SimXfer.java)のリスト

/* Copyright 1999 Oracle Systems, Inc. All Rights Reserved */
import bea.jolt.*;
public class SimXfer
{
      public static void main (String[] args)
      {

         JoltSession session;
         JoltSessionAttributes sattr;
         JoltRemoteService withdrawal;
         JoltRemoteService deposit;
         JoltTransaction trans;
         String userName=null;
         String userPassword=null;
         String appPassword=null;
         String userRole=”myapp”;

         sattr = new JoltSessionAttributes();
         sattr.setString(sattr.APPADDRESS, “//bluefish:8501”);

         switch (sattr.checkAuthenticationLevel())
         {
         case JoltSessionAttributes.NOAUTH:
             System.out.println(“NOAUTH\n”);
             break;
         case JoltSessionAttributes.APPASSWORD:
             appPassword = “appPassword”;
             break;
         case JoltSessionAttributes.USRPASSWORD:
             userName = “myname”;
             userPassword = “mysecret”;
             appPassword = “appPassword”;
             break;
         }
         sattr.setInt(sattr.IDLETIMEOUT, 300);
         session = new JoltSession(sattr, userName, userRole,
         userPassword, appPassword);
         // Simulate a transfer
         withdrawal = new JoltRemoteService(“WITHDRAWAL”, session);
         deposit = new JoltRemoteService(“DEPOSIT”, session);

         withdrawal.addInt(“ACCOUNT_ID”, 100000);
         withdrawal.addString(“SAMOUNT”,“100.00”);

         // Begin the transaction w/ a 5 sec timeout
         trans = new JoltTransaction(5, session);
         try
         {
              withdrawal.call(trans);
         }
         catch (ApplicationException e)
         {
               e.printStackTrace();
              // This service uses the STATLIN field to report errors
             // back to the client application.
             System.err.println(withdrawal.getStringDef(“STATLIN”,”NO
             STATLIN”));
             System.exit(1);
         }
         String wbal = withdrawal.getStringDef(“SBALANCE”, “$-1.0”);

         // remove leading “$” before converting string to float
         float w = Float.valueOf(wbal.substring(1)).floatValue();
         if (w < 0.0)
         {
             System.err.println(“Insufficient funds”);
             trans.rollback();
             System.exit(1);
         }

         else           // now attempt to deposit/transfer the funds

         {

              deposit.addInt(“ACCOUNT_ID”, 100001);
              deposit.addString(“SAMOUNT”,“100.00”);

              deposit.call(trans);
             String dbal = deposit.getStringDef(“SBALANCE”, “-1.0”);
             trans.commit();

             System.out.println(“Successful withdrawal”);
             System.out.println(“New balance is: “ + wbal);

             System.out.println(“Successful deposit”);
             System.out.println(“New balance is: “ + dbal);
         }

           session.endSession();
           System.exit(0);
           } // end main
       } // end SimXfer