5.4 サービスの定義

すべてのサービス・ルーチンは、TPSVCINFO構造体を指すポインタで構成される1つの引数を受け取る関数として定義する必要があります。TPSVCINFO構造体は、atmi.hヘッダー・ファイルに定義され、次の情報が含まれています。

char       name[32];
long       flags;
char       *data;
long       len;
int        cd;
int        appkey;
CLIENTID   cltid;

次の表は、TPSVCINFOデータ構造体をまとめたものです。

表5-1 TPSVCINFOデータ構造体

フィールド 説明
name リクエスト元プロセスがサービスの呼出しに使用する名前をサービス・ルーチンに対して指定します。
flags サービスがトランザクション・モードであるかどうか、または呼出し側が応答を要求しているかどうかをサービスに通知します。サービスをトランザクション・モードにする各方法については、9-1ページの「グローバル・トランザクションのコーディング」を参照してください。

TPTRANフラグは、サービスがトランザクション・モードであることを示します。tpcall()またはtpacall()のflagsパラメータにTPNOTRANを設定してサービスを呼び出した場合、サービスは現在のトランザクションに参加できません。ただし、トランザクション・モードでサービスを実行することはできます。つまり、呼出し側によってTPNOTRAN通信フラグが設定されていても、TPTRANsvcinfo->flagsに設定できます。このような状況の例については、9-1ページの「グローバル・トランザクションのコーディング」を参照してください。

tpacall()TPNOREPLY通信フラグが設定されてサービスが呼び出された場合、flagsメンバーはTPNOREPLYに設定されます。呼び出されたサービスが、呼出し側プロセスと同じトランザクションに含まれる場合は、呼出し側に応答を戻す必要があります。

data main()内でtpalloc()によってすでに割り当てられているバッファを指すポインタ。このバッファは、リクエスト・メッセージの受信に使用されます。ただし、応答メッセージの返信やリクエスト・メッセージの転送にも、このバッファを使用することをお薦めします。
len dataフィールドによって参照されるバッファ内のリクエスト・データの長さを格納します。
cd 会話型通信の場合は、接続記述子を指定します。
appkey アプリケーションで使用するために予約された値。アプリケーション固有の認証が設計に含まれている場合、クライアントがアプリケーションに参加するときに呼び出されるアプリケーション固有の認証サーバーによって、認証の成功または失敗を示す値、およびクライアント認証キーが戻される必要があります。Oracle Tuxedoシステムは、appkeyをクライアントのために保持し、このフィールドに情報を格納して以降のサービス・リクエストに渡します。appkeyがサービスに渡されたときは、クライアントの認証は終了しています。ただし、サービス内でappkeyフィールドを使用して、サービスを呼び出したユーザー、またはそのユーザーに関するその他のパラメータを識別できます。

このフィールドが使用されていない場合は、デフォルト値の-1が割り当てられます

.
cltid クライアントの識別子の保持に使用されるCLIENTID型の構造体。この構造体は変更できません。

プロセスがTPSVCINFO構造体のdataフィールドにアクセスする場合、次のバッファ・タイプが合致する必要があります:

  • 呼出し側のプロセスによって渡されるリクエスト・バッファのタイプ
  • 呼び出されたサービスに定義された対応するバッファ・コードのタイプ
  • 呼び出されたサービスに対して構成ファイルに定義された対応するバッファのタイプ

次のリストは、一般的なサービス定義を示しています。このコードは、Oracle Tuxedoソフトウェアで提供される銀行業務アプリケーションのABAL(残高照会)サービス・ルーチンから引用したものです。ABALBALサーバーの一部です。

一般的なサービス定義のリスト

#include <stdio.h>           /* UNIX */
#include <atmi.h>            /* ORACLE Tuxedo System */
#include <sqlcode.h>         /* ORACLE Tuxedo System */
#include "bank.flds.h"       /* bankdb fields */
#include "aud.h"             /* BANKING view defines */

EXEC SQL begin declare section;
static long branch_id;  /* branch id */
static float bal;            /* balance */
EXEC SQL end declare section;

 /*
  * Service to find sum of the account balances at a SITE
  */

void
#ifdef __STDC__
ABAL(TPSVCINFO *transb)

#else

ABAL(transb)
TPSVCINFO *transb;
#endif

{
     struct aud *transv;           /* view of decoded message */

     /* Set pointer to TPSVCINFO data buffer */

     transv = (struct aud *)transb->data;

     set the consistency level of the transaction   
       
     /* Get branch id from message, do query */ 

     EXEC SQL declare acur cursor for
       select SUM(BALANCE) from ACCOUNT;
     EXEC SQL open acur;           /* open */
     EXEC SQL fetch acur into :bal;   /* fetch */
     if (SQLCODE != SQL_OK) {      /* nothing found */
      (void)strcpy (transv->ermsg,"abal failed in sql aggregation");
      EXEC SQL close acur;
      tpreturn(TPFAIL, 0, transb->data, sizeof(struct aud), 0);
      }
      EXEC SQL close acur;
      transv->balance = bal;
      tpreturn (TPSUCCESS, 0, transb->data, sizeof(struct aud), 0);
}

前述の例では、アプリケーションがクライアント側にリクエスト・バッファを割り当てるために、tpalloc()の呼出しでtypeパラメータにVIEWsubtypeaudが設定されています。ABALサービスは、VIEW型付きバッファをサポートするサービスとして定義されています。ABALにはBUFTYPEパラメータは指定されず、デフォルト値のALLが使用されます。ABALサービスはVIEW型のバッファを割り当て、このバッファへのポインタにABALサブルーチンが渡されたTPSVCINFO構造体のdataメンバーを割り当てます。ABALサーバーは、前述のサンプル・コードに示してあるように、対応するdataメンバーにアクセスして適切なデータ・バッファを取得します。

ノート:

このバッファが取得された後、データベースへの最初のアクセスを行う前に、サービスでトランザクションの整合性レベルを指定する必要があります。トランザクションの整合性レベルの詳細は、「グローバル・トランザクションのコーディング」を参照してください。