ページの先頭行へ戻る
Interstage Application Server アプリケーション作成ガイド(データベース連携サービス編)

3.4.2 ソースの作成

3.4.2.1 アプリケーションの構成

  グローバルトランザクション運用を行うためには、CORBAのクライアントアプリケーションの処理に加えて、CosTransactions.Current.commitメソッドなどのCurrentインタフェースを呼び出して、データベース連携サービスにトランザクション処理を依頼します。


  これらの処理を考慮したクライアントアプリケーションの構成について以下に示します。



初期化処理部

  クライアントアプリケーションをCORBAサービスに登録、およびトランザクションサービスの初期化を行います。


アプリケーション固有部

  アプリケーション固有の処理部です。トランザクションの開始から終了までの流れを記述します。


トランザクション用ライブラリ

  データベース連携サービスが提供するクライアントアプリケーション用ライブラリです。


  クライアントアプリケーションの基本形を以下に示します。


try{

    /* 初期化処理 */
                :
    orb = org.omg.CORBA.ORB.init(args, null);
                :
    /* ネーミングサービスのオブジェクトリファレンスの獲得 */
                :
    org.omg.CORBA.Object _tmpObj2 =
                   Orb.resolve_initial_references("NameService");
    Cos  =  org.omg.NamingContextExtHelper.narrow(_tmpObj2);                … (1)
                :
    /* トランザクション依頼処理 */
    org.omg.CORBA.Object  _tmpObj1 =
                   Orb.resolve_initial_references("TransactionCurrent");
    Current  = org.omg.CosTransactions.CurrentHelper.narrow(_tmpObj1);   … (2)
                :
    /* サーバアプリケーションのオブジェクトリファレンス獲得 */
    String NCid = new String("bankA::accountA");
    String NCkind = new String("");
    
    try {
        NameComponent nc = new NameComponent( NCid, NCkind );
        NameComponent NCo[] = { nc };
        Obj = Cos.resolve( NCo );
        target = accountAHelper.narrow( Obj );
    }

    Current.begin();                                                   … (3)
                :
    obj->ope1(para);                                                   … (4)

    Current.commit(rhuristic);                                         … (5)
}
catch( org.omg.CORBA.SystemException e) {
    Current.rollback();                                                … (6)
}
catch( java.lang.Exception e) {
    Current.rollback();                                                … (6)
}

  1. ネーミングサービスからサーバアプリケーションのオブジェクトリファレンスを獲得します。

  2. Currentインタフェースのオブジェクトリファレンスを獲得します。

  3. CosTransactions.Current.beginメソッドでトランザクションの開始を宣言します。

  4. サーバアプリケーションを呼び出します。

  5. サーバアプリケーションの復帰状態を確認して、トランザクションの状態を決定します。トランザクションを正常終了する場合は、CosTransactions.Current.commitメソッドでトランザクションをコミットします。

  6. 異常終了する場合は、CosTransactions.Current.rollbackメソッドでトランザクションをロールバックします。


3.4.2.2 形態の説明

  クライアントアプリケーションからサーバアプリケーションを呼び出す形態を以下に示します。


同期型

  サーバアプリケーションを呼び出し、サーバアプリケーションのメソッドが終了した時点でクライアントアプリケーションに制御が戻ります。

非同期型

  サーバアプリケーションを呼び出し、サーバアプリケーションのメソッドの終了を待たずにクライアントアプリケーションに制御が戻ります。クライアントアプリケーションは任意のタイミングでサーバアプリケーションのメソッドの終了を問い合わせます。


同期型

呼出し形態

  同期型呼出しは、クライアントアプリケーションからサーバアプリケーションを呼び出し、そのサーバアプリケーションの処理終了を待ち合わせる呼出し形態です。同期型の呼出し形態について、以下に示します。



インタフェース

  同期型には、以下の2つのインタフェースがあります。詳細については、“リファレンスマニュアル(API編)”を参照してください。

  • 静的起動インタフェース
      サーバアプリケーションのメソッド名を指定して呼び出します。

  • 動的起動インタフェース
      Requestインタフェースのinvokeメソッドでサーバアプリケーションを呼び出します。

  動的起動インタフェースにおいて、遅延同期送信を行う場合の注意事項を以下に示します。


遅延同期送信の呼出し

  遅延同期送信の呼出し元は、その呼出しの復帰が完了するまでデータベースの操作を禁止します。


遅延同期送信で呼び出されたサーバ

  遅延同期送信の呼出し先は、データベースを使用する場合には、複数の呼出しが同じデータベースにアクセスできません。


同一データベースへのアクセス

  遅延同期送信で呼び出されたアプリケーションから、同時に同一のデータベースを操作することはできません。



異なるデータベースへのアクセス

  遅延同期送信で呼び出されたアプリケーションから、異なるデータベースを操作することができます。



アプリケーションの処理論理

  同期型を使用する場合のクライアントアプリケーションの処理論理を以下に示します。



  1. サーバアプリケーションAのメソッド1を呼び出します。クライアントアプリケーションは、サーバアプリケーションAのメソッドが終了するまで待ち合わせます。

  2. クライアントアプリケーションは、サーバアプリケーションAのメソッド1の処理が終了した時点で制御が戻ります。

  3. サーバアプリケーションBのメソッド2を呼び出します。クライアントアプリケーションは、サーバアプリケーションBのメソッドが終了するまで待ち合わせます。

  4. クライアントアプリケーションは、サーバアプリケーションBのメソッド2の処理が終了した時点で制御が戻ります。


非同期型

呼出し形態

  非同期型呼出しは、クライアントアプリケーションからサーバアプリケーションを呼び出し、サーバアプリケーションのメソッドの終了を待たずにクライアントアプリケーションに制御が戻ります。クライアントアプリケーションは任意のタイミングでサーバアプリケーションのメソッドの終了結果を問い合わせる呼出し形態です。
  非同期型の呼出し形態を以下に示します。



インタフェース

  Requestインタフェースを使用します。詳細については、“リファレンスマニュアル(API編)”を参照してください。


アプリケーションの処理論理

  非同期型を使用する場合のクライアントアプリケーションの処理論理を以下に示します。



  1. サーバアプリケーションAのメソッド1を非同期型で呼び出します。

  2. サーバアプリケーションBのメソッド2を非同期型で呼び出します。

  3. メソッド1の処理終了を問い合わせます。

  4. メソッド2の処理終了を問い合わせます。


3.4.2.3 静的起動インタフェース

  静的起動インタフェースでサーバアプリケーションを呼び出す場合の、クライアントアプリケーションの記述例について説明します。


初期化

  初期化処理として、ORBのオブジェクトリファレンスを取得します。オブジェクトリファレンスを取得するには、初期化メソッドを呼び出します。
  記述例を以下に示します。


アプリケーションの場合の例
public class Sample {                // クラスの宣言
    public static void main( String args[] ) {
        org.omg.CORBA.ORB   Orb;     // ORBオブジェクト

        try {
            // ORBの生成と初期化
            Orb = org.omg.CORBA.ORB.init( args, null ); 
                 ... 
        }
        catch( java.lang.Exception e ) {
                 ...                 // 例外処理
        }
    }
}

アプレットの場合の例
public class Sample extends java.applet.Applet { // appletクラスの宣言

    public void init() {
        ...                                      // 画面表示処理
    }

    public void start() {
        org.omg.CORBA.ORB   Orb;                 // ORB用オブジェクト

    try {
        // ORBの生成と初期化
        Orb = org.omg.CORBA.ORB.init( this, null ); 
              ... 
    }
    catch( java.lang.Exception e ) {
            ...                                  // 例外処理
    }
}

ネーミングサービスのオブジェクトリファレンスの獲得

  実行するオブジェクトをネーミングサービスから検索するために、ネーミングサービスのオブジェクトリファレンスを取得します。ネーミングサービスのオブジェクトリファレンスには、CORBAインタフェースのオブジェクトリファレンスの取り出しメソッドを使用します。
  処理の記述例を以下に示します。


// NamingService用オブジェクトリファレンス
org.omg.CosNaming.NamingContextExt  Cos; 

// ネーミングサービスのオブジェクトリファレンスの取得
try {
    org.omg.CORBA.Object _tmpObj =
                            Orb.resolve_initial_references( "NameService" ); 
    Cos  = org.omg.CosNaming.NamingContextExtHelper.narrow( _tmpObj ); 
             ... 
}
catch( java.lang.Exception e ) {
             ...  // 例外処理
}

サーバアプリケーションのオブジェクトリファレンスの獲得

  ネーミングサービスのメソッドCosNaming.NamingContext.resolve()により、これから実行したいサーバアプリケーションのオブジェクトリファレンスを取り出します。検索したいオブジェクト名を当メソッドのパラメタとして指定します。

  処理の記述例を以下に示します。


// ネーミングサービスのresolveメソッドを発行して
// サーバアプリケーションのオブジェクトリファレンスの獲得
String NCid   = new String( "ODdemo::calculator" ); // オブジェクト名
String NCkind = new String( "" );                   // オブジェクトタイプ
try {
    org.omg.CosNaming.NameComponent nc =  new NameComponent( NCid, NCkind ); 
    org.omg.CosNaming.NameComponent NCo[] = { nc };

    // NamingServiceのresolveメソッド発行
    org.omg.CORBA.Object  Obj = Cos.resolve( NCo ); 
            ... 
}
catch( java.lang.Exception e ) {
            ...                                     // 例外処理
}

トランザクションの開始

  トランザクションを開始するために、Currentインタフェースのオブジェクトリファレンスを取得し、CosTransactions.Current.beginメソッドを呼び出します。
  処理の記述例を以下に示します。


static org.omg.CosTransactions.Current current;  // トランザクション開始オブジェクトリファレンス
  
// トランザクション開始インタフェースのオブジェクトリファレンスを獲得
org.omg.CORBA.Object  _tmpObj1 =
                   Orb.resolve_initial_references("TransactionCurrent");
current  = org.omg.CosTransactions.CurrentHelper.narrow(_tmpObj1);

// トランザクション開始メソッドの呼出し
current.begin();

サーバオブジェクトのメソッド起動

  サーバプログラムのメソッドを呼び出します。メソッド名はIDLで指定したモジュール名、インタフェース名およびオペレーション名をドット(.)でつなげた形式で指定します。この例では、ODdemo、calculator、calculateがそれにあたります。なお、メソッド呼出し時にネーミングサービスで求めたサーバアプリケーションのオブジェクトリファレンスとサーバプログラムで例外が発生した場合に例外情報を設定するためにtry-catchブロックを指定します。
  処理の記述例を以下に示します。


ODdemo.calculator target;    // アプリケーション用オブジェクトリファレンス
try {
    // ODdemo.calculatorクラスへの変換
    target = ODdemo.calculatorHelper.narrow(Obj); 
    ODdemo.calculatorPackage.result res = new ODdemo.calculatorPackage.result();
    res = target.calculate( a, b ); 
           ... 
}
catch( NumberFormatException e ){ 
           ...               // 例外処理
}
catch( ODdemo.calculatorPackage.ZEROPARAM e ){ 
           ...               // 例外処理
}
catch( org.omg.CORBA.SystemException err ){ 
           ...               // 例外処理
}

トランザクションの完了

  サーバアプリケーションのメソッド呼出しの結果を復帰状態から判断し、トランザクションの状態を決定します。トランザクションを正常終了する場合は、CosTransactions.Current.commitメソッドを呼び出し、トランザクションをコミットします。トランザクションを異常終了する場合は、CosTransactions.Current.rollbackメソッドを呼び出し、トランザクションをロールバックします。
  処理の記述例を以下に示します。


boolean                rhuristic;
   ...
rhuristic = true;
try {
    current.commit( rhuristic );
}catch( NoTransaction e) {
    ...                // 例外処理
}
    ...
current.rollback( );

3.4.2.4 動的起動インタフェース

  動的起動インタフェースでサーバアプリケーションを呼び出す場合の、クライアントアプリケーションの記述例について説明します。


初期化

  初期化処理として、ORBのオブジェクトリファレンスを取得します。オブジェクトリファレンスを取得するには、初期化メソッドを呼び出します。
  記述例を以下に示します。


static org.omg.CORBA.ORB Orb;    // ORB用オブジェクトリファレンス
public void initialize(){
    try {
        // ORBの初期化処理
        Orb = org.omg.CORBA.ORB.init( arg, null ); 
          ... 
    }
    catch( java.lang.Exception e ){ 
          ... 
    }
} // initialize()

ネーミングサービスのオブジェクトリファレンスの獲得

  実行するオブジェクトをネーミングサービスから検索するために、ネーミングサービスのオブジェクトリファレンスを取得します。ネーミングサービスのオブジェクトリファレンスには、CORBAインタフェースのオブジェクトリファレンスの取り出しメソッドを使用します。
  処理の記述例を以下に示します。


org.omg.CosNaming.NamingContextExt Cos; // NamingService用オブジェクトリファレンス
try {
    // NamingServiceのオブジェクトリファレンスの取得
    org.omg.CORBA.Object _tmpObj = 
              Orb.resolve_initial_references( “NameService” ); 
    Cos = org.omg.CosNaming.NamingContextExtHelper.narrow( _tmpObj ); 
    if( Cos == null ){ 
          ...; 
    }
}
catch( java.lang.Exception e ){ 
      ...                               // 例外処理
}

インタフェースリポジトリのサーバアプリケーション情報の獲得

  インタフェースリポジトリには、IDLで定義されたモジュール名、インタフェース名、オペレーション名、パラメタが階層構造で格納されています。インタフェースリポジトリからサーバアプリケーションの情報を獲得する方法について、以下に示します。


(1) InterfaceDefオブジェクトリファレンスの獲得

  インタフェースリポジトリからサーバアプリケーションの情報を取得するためには、InterfaceDefオブジェクトのオブジェクトリファレンスが必要です。InterfaceDefオブジェクトのオブジェクトリファレンスを求めるには、オブジェクト名をパラメタとして、ネーミングサービスからサーバアプリケーションのオブジェクトリファレンスを求めたあと、CORBA_Object_get_interface()メソッドにより、InterfaceDefオブジェクトリファレンスを取得します。
  処理の記述例を以下に示します。


try {
    String NCid = new String( "ODdemo::calculator" );  // オブジェクト名
    String NCkind = new String( "" );                  // オブジェクトのタイプ

    // オブジェクト名、タイプの設定
    org.omg.CosNaming.NameComponent nc = 
                     new org.omg.CosNaming.NameComponent( NCid, NCkind ); 
    org.omg.CosNaming.NameComponent NCo[] = { nc };

    //NamingServiceのresolveメソッドを発行
    org.omg.CORBA.Object target = Cos.resolve( NCo ); 

    // org.omg.CORBA.InterfaceDefオブジェクトリファレンス取得
    org.omg.CORBA.InterfaceDef intf = target._get_interface();
}
catch( java.lang.Exception e ) {
      ...         // 例外処理
}

(2) OperationDefオブジェクトリファレンスの取得

  サーバアプリケーションのメソッド名をパラメタとして、CORBA_InterfaceDef_lookup_name()メソッドにより、指定されたメソッドをインタフェースリポジトリから検索します。このメソッドにより、指定したメソッド情報が格納されているOperationDefオブジェクトのオブジェクトリファレンスが通知されます。
  処理の記述例を以下に示します。


// メソッドのorg.omg.CORBA.OperationDefオブジェクトリファレンス取得
String name = new String( "calcurate" ); 
org.omg.CORBA.Contained[] intf_opr =
    intf.lookup_name( name, -1, org.omg.CORBA.DefinitionKind.dk_Operation, false );

(3) パラメタ情報の取得

  org.omg.CORBA.Contained.describe()メソッドにより、サーバアプリケーションがもっているメソッドのパラメタの情報(パラメタの名前、個数、パラメタの型など)をインタフェースリポジトリから検索します。パラメタとして、org.omg.CORBA.OperationDefオブジェクトリファレンスを指定します。


org.omg.CORBA.ContainedPackage.Description desc = intf_opr[0].describe();
// 指定されたメソッドのパラメタ情報を検索

トランザクションの開始

  トランザクションを開始するために、Currentインタフェースのオブジェクトリファレンスを取得し、CosTransactions.Current.beginメソッドを呼び出します。
  処理の記述例を以下に示します。


static org.omg.CosTransactions.Current current;  // トランザクション開始オブジェクトリファレンス
  
// トランザクション開始インタフェースのオブジェクトリファレンスを獲得  
org.omg.CORBA.Object  _tmpObj1 =
                   Orb.resolve_initial_references("TransactionCurrent");
current  = org.omg.CosTransactions.CurrentHelper.narrow(_tmpObj1);

// トランザクション開始メソッドの呼出し
current.begin();

パラメタの組み立て

(1) パラメタリストの生成

  org.omg.CORBA.ORB.create_list()メソッドにより、サーバアプリケーションに渡すパラメタを格納するための領域を保持するリストオブジェクトを生成します。このとき、何個のパラメタを格納するかを指定します。結果として、NVListオブジェクトリファレンスが通知されます。
  処理の記述例を以下に示します。


org.omg.CORBA.NVList Nvl;  // NVList

// org.omg.CORBA.ContainedPackage.Description構造体からパラメタ情報構造体の抽出
org.omg.CORBA.Any opeany = desc.value; 
org.omg.CORBA.OperationDescription c
                    = org.omg.OperationDescriptionHelper.extract( opeany ); 
org.omg.CORBA.ParameterDescription[] paraseq = c.parameters; 

// パラメタ情報の抽出
int ParamCount = paraseq.length; 

// リストオブジェクトの生成
Nvl = Orb.create_list( ParamCount );

(2) パラメタリストの設定

  org.omg.CORBA.NVList.add_value()メソッドにより、サーバアプリケーションに渡すパラメタをリストオブジェクトに設定します。パラメタとして、サーバアプリケーションのパラメタの名前、値(Any型)およびパラメタの形式を設定します。
  処理の記述例を以下に示します。


org.omg.CORBA.NamedValue tmpNam; 
org.omg.CORBA.Any  Anya = Orb.create_any();
Anya.insert_long(a); 
tmpNam = Nvl.add_value( paraseq[0].name, Anya, org.omg.CORBA.ARG_IN.value ); 
org.omg.CORBA.Any  Anyb = Orb.create_any();
Anyb.insert_long(b); 
tmpNam = 
    Nvl.value.add_value( paraseq[1].name, Anyb, org.omg.CORBA.ARG_IN.value );

リクエストの作成

  org.omg.CORBA.Object._create_request()メソッドにより、リクエストオブジェクトを作成します。リクエストオブジェクトに対して、サーバオブジェクトのオブジェクトリファレンス、org.omg.CORBA.NVListオブジェクトリファレンス、org.omg.CORBA.NamedValueと呼ぶサーバの処理結果を格納する領域を指定します。結果として、リクエストオブジェクトが返されます。
  処理の記述例を以下に示します。


// 復帰パラメタ
org.omg.CORBA.Any AnyResult = Orb.create_any();
AnyResult.type(c.result); 

// 復帰パラメタ格納域
org.omg.CORBA.NamedValue Result =
         Orb.create_named_value( null, AnyResult, org.omg.CORBA.ARG_OUT.value); 
String OpName = new String(c.name); 

// リクエストオブジェクトの生成
org.omg.CORBA.Request Req = target._create_request(
      null,      // context
      OpName,    // メソッド名
      Nvl,       // 入力パラメタ
      Result);   // 復帰値

リクエストの送信

  サーバアプリケーションに対してリクエストを送信します。リクエストの方法として、以下の方法があります。

  それぞれについて、以下に示します。


同期送信

  org.omg.CORBA.Request.invoke()メソッドにより、サーバアプリケーションを呼び出します。
  処理の記述例を以下に示します。


Req.invoke();

非同期送信

  org.omg.CORBA.Request.send_deferred()メソッドにより、サーバアプリケーションを呼び出します。サーバアプリケーションの処理結果は、org.omg.CORBA.Request.get_response()メソッドにより受け取ります。
  処理の記述例を以下に示します。


Req.send_deferred();   // 処理の要求
Req.get_response();    // 処理結果の受取り

  org.omg.CORBA.Request.get_response()サーバアプリケーションからリクエストが完了していないことが判明した場合、再度org.omg.CORBA.Request.get_response()メソッドを呼び出します。


トランザクションの完了

  サーバアプリケーションのメソッド呼出しの結果を復帰状態から判断し、トランザクションの状態を決定します。トランザクションを正常終了する場合は、CosTransactions.Current.commitメソッドを呼び出し、トランザクションをコミットします。トランザクションを異常終了する場合は、CosTransactions.Current.rollbackメソッドを呼び出し、トランザクションをロールバックします。
  処理の記述例を以下に示します。


boolean                rhuristic;
   ...
rhuristic = true;
try {
    current.commit( rhuristic );
} catch( NoTransaction e) {
    ...   // 例外処理
}
    ...
current.rollback( );