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

3.1.2 ソースの作成

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

  グローバルトランザクション運用を行うためには、CORBAのクライアントアプリケーションの処理に加えて、CosTransactions_Current_commitメソッドなどのCurrentインタフェースを呼び出して、データベース連携サービスにトランザクション処理を依頼します。
  これらの処理を考慮したクライアントアプリケーションの構成について以下に示します。



初期化処理部

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


アプリケーション固有部

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


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

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


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

/* 初期化処理  */
orb = CORBA_ORB_init(&argc, argv, FJ_OM_ORBid, &env);
                        :
obj = CosNaming_NamingContext_resolve(naming, name, &env); … (1)
                        :
/* トランザクション依頼処理 */
Current = CORBA_ORB_resolve_initial_references(
           orb,
           CORBA_ORB_ObjectId_TransactionCurrent, &env);   … (2)
CosTransactions_Current_begin(Current, &env);              … (3)
                        :
mod_intf_ope1(obj, para, &env);                            … (4)
                        :
if (env._major != CORBA_NO_EXCEPTION)                      … (5)
CosTransactions_Current_rollback(Current, &env);
else
CosTransactions_Current_commit(Current, CORBA_TRUE, &env);
                        :

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

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

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

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

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


3.1.2.2 形態の説明

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


同期型

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

非同期型

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


同期型

呼出し形態

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



インタフェース

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

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

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

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


遅延同期送信の呼出し元

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


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

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


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

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



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

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



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

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



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

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

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

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


非同期型

呼出し形態

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



インタフェース

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


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

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



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

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

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

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


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

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


初期化

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

main( argc, argv )
    int   argc;
    char *argv[];
{
    int     current_argc = argc;
    CORBA_ORB               orb;    /* ORBのオブジェクトリファレンス */
    CORBA_Environment       env;    /* 例外情報 */

    orb = CORBA_ORB_init(&current_argc,argv, FJ_OM_ORBid, &env );
                  :
}

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

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

CosNaming_NamingContext  cos_naming;      /* NamingServiceのオブジェクトリファレンス */
CosNaming_Name           name;            /* 検索したい情報格納域 */
CosNaming_NameComponent  name_component;  /* オブジェクト格納域   */

/* NamingServiceのオブジェクトリファレンスを獲得 */
cos_naming = CORBA_ORB_resolve_initial_references (
        orb,
        CORBA_ORB_ObjectId_NameService,
        &env);

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

  ネーミングサービスから、実行したいサーバアプリケーションの情報を検索します。サーバアプリケーションの情報を取り出すには、実行するサーバアプリケーションのオブジェクト名をパラメタとしてメソッドを起動し、オブジェクトリファレンス情報が格納されているネーミングコンテキストを取得します。
  処理の記述例を以下に示します。

CORBA_Object obj;                          /* サーバアプリケーションのオブジェクトリファレンス */
name._length = name._maximum = 1;          /* オブジェクト名の数 */
name._buffer = &name_component;            /* オブジェクト名格納域 */
name_component.id = "ODdemo::calculator";  /* オブジェクト名 */
name_component.kind = "";                  /* オブジェクトのタイプ */

/* サーバアプリケーションのオブジェクトリファレンスを獲得 */
obj = CosNaming_NamingContext_resolve(cos_naming, &name, &env );

トランザクションの開始

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

CORBA_Object  Current;      /* トランザクション開始オブジェクトリファレンス */

/* トランザクション開始インタフェースのオブジェクトリファレンスを獲得 */
Current = CORBA_ORB_resolve_initial_references(
            orb,
            CORBA_ORB_ObjectId_TransactionCurrent,
            &env);

/* トランザクション開始メソッドの呼出し */
CosTransactions_Current_begin(Current, &env);

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

  サーバプログラムのメソッドを呼び出します。メソッド名は、IDLで指定したモジュール名、インタフェース名、およびオペレーション名をアンダースコア(_)でつなげた形式で指定します。この例では、ODdemo、calculator、およびcalculateが該当します。なお、メソッド呼出し時にネーミングサービスから取得したサーバアプリケーションのオブジェクトリファレンス、およびサーバプログラムで例外が発生した場合、例外情報を獲得するためにCORBA_Environment構造体を指定します。
  処理の記述例を以下に示します。

CORBA_long                a,b;  /* 入力パラメタ */
ODdemo_calculator_result  res;  /* 復帰値 */

a = 100; b = 20;

/* メソッドの呼出し */
res = ODdemo_calculator_calculate( obj, a, b, &env );

トランザクションの完了

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

/* サーバアプリケーションのメソッド呼出しの復帰状態を確認 */
if(env._major  != CORBA_NO_EXCEPTION)
    CosTransactions_Current_rollback(Current, &env);
else
    CosTransactions_Current_commit(Current, CORBA_TRUE, &env);

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

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


初期化

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

main( argc, argv )
    int     argc;
    char    *argv[];
{
    int     current_argc = argc;
    CORBA_Environment      env;    /* 例外情報 */
    CORBA_ORB              orb;    /* ORBのオブジェクトリファレンス */

    orb = CORBA_ORB_init(&current_argc,argv, FJ_OM_ORBid, &env );

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

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

CosNaming_NamingContext  cos_naming;  /* NamingServiceのオブジェクトリファレンス */
CORBA_Environment        env;         /* 例外情報 */

/* NamingServiceのオブジェクトリファレンスを獲得 */
cos_naming = CORBA_ORB_resolve_initial_references (
                orb,
                CORBA_ORB_ObjectId_NameService,
                &env);

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

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


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

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

CosNaming_Name           name;            /* 検索したい情報格納域 */
CosNaming_NameComponent  name_component;  /* オブジェクト格納域   */
CORBA_Object             obj;             /* サーバアプリケーションのオブジェクトリファレンス */
CORBA_InterfaceDef       intf;            /* InterfaceDefオブジェクトリファレンス */

name._length = name._maximum = 1;         /* オブジェクト名の数 */
name._buffer = &name_component;           /* オブジェクト名格納域 */
name_component.id = "ODdemo::calculator"; /* オブジェクト名 */
name_component.kind = "";                 /* オブジェクトのタイプ */

/* サーバアプリケーションのオブジェクトリファレンスを獲得 */
obj = CosNaming_NamingContext_resolve (
        cos_naming,
        &name,
        &env );

/* InterfaceDefオブジェクトリファレンス取得 */
intf = CORBA_Object_get_interface(obj, &env);

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

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

CORBA_ContainedSeq      *intf_opr;

/* メソッドのOperationDefオブジェクトリファレンス取得 */
intf_opr = (CORBA_OperationDef)CORBA_InterfaceDef_lookup_name(
            intf,
            "calculate",
            -1,
            CORBA_dk_Operation,     /* Operation情報の取得 */
            CORBA_FALSE,
            &env );

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

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

/* OperationDefオブジェクトが保持しているパラメタ情報の構造体 */
CORBA_Contained_Description     *description;

/* パラメタ情報の構造体の取得 */
description = CORBA_OperationDef_describe( intf_opr->_buffer[0], &env );

トランザクションの開始

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

CORBA_Object  Current;  /* トランザクション開始オブジェクトリファレンス */

/* トランザクション開始インタフェースのオブジェクトリファレンスを獲得 */
Current = CORBA_ORB_resolve_initial_references(
            orb,
            CORBA_ORB_ObjectId_TransactionCurrent,
            &env);

/* トランザクション開始メソッドの呼出し */
CosTransactions_Current_begin(Current, &env);

パラメタの組み立て


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

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

CORBA_OperationDescription      *opr_description;    /* パラメタ情報の構造体 */
CORBA_any                       *tmp_any;            /* ワーク用 */
CORBA_ParDescriptionSeq         *params;             /* パラメタ情報 */
CORBA_NVList                    arg_list;            /* リストオブジェクト */
CORBA_long                      a,b;                 /* 入力パラメタ */

/* Contained_Description構造体から構造体の抽出 */
tmp_any = &description->value;
opr_description = (CORBA_OperationDescription *)tmp_any->_value;

/* パラメタ情報の抽出 */
params = &opr_description->parameters;

/* リストオブジェクトの生成 */
CORBA_ORB_create_list( orb,
        params->_length,
        &arg_list,
        &env );

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

  CORBA_NVListオブジェクトリファレンス、サーバアプリケーションのパラメタの名前、型、値、および長さをパラメタとしてCORBA_NVList_add_item()メソッドにより、サーバアプリケーションに渡すパラメタをリストオブジェクトに設定します。
  処理の記述例を以下に示します。

/* パラメタの設定 */
CORBA_NVList_add_item(
    arg_list,                       /* リストオブジェクト */
    params->_buffer[0].name,        /* パラメタ名 */
    TC_long,                        /* パラメタの型 */
    &a,                             /* パラメタの値 */
    sizeof( CORBA_long ),           /* パラメタの長さ */
    CORBA_ARG_IN,                   /* パラメタのタイプ(in, out, inout) */
    &env);

CORBA_NVList_add_item(
    arg_list,                       /* リストオブジェクト */
    params->_buffer[1].name,        /* パラメタ名 */
    TC_long,                        /* パラメタの型 */
    &b,                             /* パラメタの値 */
    sizeof( CORBA_long ),           /* パラメタの長さ */
    CORBA_ARG_IN,                   /* パラメタのタイプ(in, out, inout) */
    &env);

リクエストの作成

  CORBA_Object_create_request()メソッドにより、リクエストオブジェクトを作成します。リクエストとは、メソッド名にパラメタを加えたものです。リクエストオブジェクトに対して、サーバオブジェクトのオブジェクトリファレンス、NVListオブジェクトリファレンス、後述するNamedValueと呼ぶサーバの処理結果を格納する領域を指定することによりリクエストオブジェクトのオブジェクトリファレンスが通知されます。
  処理の記述例を以下に示します。

CORBA_NamedValue        result;                       /* 復帰 */
CORBA_Request           request;                      /* リクエストオブジェクト */

result.argument._type = TC_ODdemo_calculator_result;  /* 復帰パラメタの型 */
result.len = sizeof( ODdemo_calculator_result );      /* 復帰パラメタの長さ */
result.argument._value = NULL;

/*リクエストオブジェクトの生成 */
CORBA_Object_create_request(
    obj,               /* サーバアプリケーションのオブジェクトリファレンス */
    CORBA_OBJECT_NIL,  /* context */
    "calculate",       /* メソッド名 */
    arg_list,          /* 入力パラメタ */
    &result,           /* 復帰値 */
    &request,
    CORBA_OUT_LIST_MEMORY,
    &env );

  NamedValueは、サーバの処理結果を格納するための領域です。
  システムで定義する定義例を以下に示します。


IDLファイルの定義例
module CORBA
{
    struct NamedValue
    {
        identifier      name;        // パラメタの名前  
        any             argument;    // パラメタの値    
        long            len;         // パラメタの長さ  
        Flags           arg_modes;   // パラメタの引き渡し方法(in,out, inout)
    };
};

C言語での定義例
struct  CORBA_NamedValue
{
    CORBA_identifier    name;       /* パラメタの名前 */
    CORBA_any           argument;   /* パラメタの値   */
    CORBA_long          len;        /* パラメタの長さ */
    CORBA_Flags         arg_modes;  /* パラメタの引き渡し方法(in,out,inout) */
};

リクエストの送信

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

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


同期送信

  リクエストオブジェクトのオブジェクトリファレンスをパラメタとして、CORBA_Request_invoke()メソッドにより、サーバアプリケーションを呼び出します。
  処理の記述例を以下に示します。

CORBA_Request_invoke( request, NULL, &env );

非同期送信

  リクエストオブジェクトのオブジェクトリファレンスをパラメタとして、CORBA_Request_send()メソッドにより、サーバアプリケーションを呼び出します。サーバアプリケーションの処理結果は、CORBA_Request_get_response()メソッドにより受け取ります。
  処理の記述例を以下に示します。

CORBA_Request_send( request, CORBA_INV_NO_RESPONSE, &env ); /* 処理の要求 */
            .....
if ( CORBA_Request_get_response(                            /* 処理結果の受取り */
                                request,
                                CORBA_RESP_NO_WAIT,
                                &env ) == CORBA_OK ) {      /* ユーザ指定の処理 */
            .....
}

リクエストの削除

  リクエストオブジェクトのオブジェクトリファレンスをパラメタとして、CORBA_Request_delete()メソッドにより、リクエストオブジェクトを削除します。
  処理の記述例を以下に示します。

CORBA_Request_delete( request, &env ); /*リクエストオブジェクトの削除 */

トランザクションの完了

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

/*サーバアプリケーションのメソッド呼出しの復帰状態を確認 */
if (env._major != CORBA_NO_EXCEPTION)
    CosTransactions_Current_rollback(Current, &env);
else
    CosTransactions_Current_commit(Current, CORBA_TRUE, &env);