Hitachi

OpenTP1 Version 7 分散トランザクション処理機能 OpenTP1 プログラム作成リファレンス C言語編


7.4.1 XATMIインタフェースの例

〈この項の構成〉

(1) リクエスト/レスポンス型サービスの通信の例

(a) 処理の概要

ここで示す例題の処理概要を,次に説明します。

[説明]宿泊施設の空き状況を調べるサービスと,飛行機の空き状況を調べるサービスを,SUPから呼びます。前者は非同期に,後者は同期的に応答を受信します。

(b) UAPの構成

例題のUAPの構成を次の図に示します。

図7‒4 同期的に応答を受信するリクエスト/レスポンス型サービスの通信形態

[図データ]

(c) 通信に使う型付きバッファ

通信に使う型付きバッファの構造体を次に示します。

struct hotel {                   struct plane {
    DCLONG date;                     DCLONG date;
    char place[128];                 char dest[128];
    char hname[128];                 DCLONG departure;
    DCLONG status;                   DCLONG status;
 }                                }

(d) SUPの例

  • XATMIインタフェース定義の例

    リクエスト/レスポンス型サービスの例題で示すSUPのXATMIインタフェース定義を次に示します。

      10  /* SUPのXATMIインタフェース定義の例(rrsup.defファイル)*/
      20  called_servers = { "rrspp.def" };
  • SUPのコーディング例

    リクエスト/レスポンス型サービスの例題で示すSUPのコーディング例を次に示します。

      10  /* SUPの例(rrsup.cファイル)*/
      20  #include <stdio.h>
      30  #include <stdlib.h>
      40  #include <string.h>
      50  #include <dcrpc.h>
      60  #include <xatmi.h>
      70  #include <dcadm.h>
      80  /*
      90   * XATMIスタブヘッダファイル
     100   */
     110  #include "rrsup_stbx.h"
     120  main()
     130  {
     140  /*
     150   * 変数の定義
     160   */
     170    struct hotel *hptr; 
     180    struct plane *pptr;
     190    struct  errmsg *werrmsg ;
     200    long  hlen, plen ;
     210    int  cd ;
     220    int rc;
     230  /*
     240   * RPC-OPEN(UAPの開始)
     250   */
     260      rc = dc_rpc_open(DCNOFLAGS);
     270      if(rc != DC_OK){
     280          printf("dc_rpc_openに失敗しました。\
     290                  ERROR CODE = %d \n", rc);
     300          goto PROG_END;
     310      }
     320  /*
     330   * ADM-COMPLETE(ユーザサーバの開始処理完了の報告)
     340   */
     350      rc = dc_adm_complete(DCNOFLAGS);
     360      if(rc != DC_OK){
     370          printf("dc_adm_completeに失敗しました。\
     380                  ERROR CODE = %d \n",  rc);
     390          goto PROG_END;
     400      }
     410  /*
     420   * TPALLOC(型付きバッファの確保)
     430   */
     440    /* 宿泊施設空き状況検索サービス用 */
     450      hptr = (struct hotel *)tpalloc("X_COMMON", "hotel", 0);
     460      if(hptr == NULL){
     470          printf("tpallocに失敗しました。\
     480                  ERROR CODE = %d \n", tperrno);
     490          goto PROG_END;
     500      }
     510    /* 飛行機空き状況検索サービス用 */
     520      pptr = (struct plane *)tpalloc("X_COMMON", "plane", 0);
     530      if(pptr == NULL){
     540          printf("tpallocに失敗しました。\
     550                  ERROR CODE = %d \n", tperrno);
     560          goto PROG_END;
     570      }
     580  /*
     590   * データの設定
     600   */
     610    hptr->date = 940415 ;
     620    strcpy(hptr->place, "SAPPORO") ;
     630    strcpy(hptr->hname, "PRINCE") ;
     640    hptr->status = 0 ;
     650    pptr->date = 940415 ;
     660    strcpy(pptr->dest, "CHITOSE") ;
     670    pptr->departure = 1540 ;
     680    pptr->status = 0 ;
     690  /*
     700   * TPACALL(サービスリクエストを送信する)
     710   */
     720      cd = tpacall("SVHOTEL", (char *) hptr, 0, 0);
     730      if(cd == -1){
     740         printf("宿泊施設空状況検索サービスの呼び出しに失敗しました。\
     750                 ERROR CODE = %d \n", tperrno);
     760         goto PROG_END;
     770      }
     780      printf("宿泊施設空状況検索サービスの呼び出しに成功しました。\n");
     790  /*
     800   * TPCALL(サービスリクエストを送信して,応答を待つ)
     810   */
     820      rc = tpcall("SVPLANE", (char *) pptr, 0, (char **) &pptr, &plen, 0);
     830      if(rc != 0){
     840          if(tperrno == TPESVCFAIL){
     850             werrmsg = (struct errmsg *) pptr ;
     860             printf("%s ERROR CODE = %d USER CODE = %d\n",
     870                     werrmsg->errmessage, tperrno, tpurcode);
     880             goto PROG_END ;
     890          }else{
     900             printf("飛行機空き状況検索サービスの呼び出しに失敗しました。 \
     910                     ERROR CODE = %d", tperrno);
     920             goto PROG_END;
     930          }
     940      }
     950      printf("飛行機空き状況検索サービスの呼び出しの応答受信に成功しました。\n");
     960      if(pptr->status == 1){
     970          printf("飛行機空き状況 : 満席です。 \n");
     980      } else {
     990          printf("飛行機空き状況 : 空席があります。 \n");
    1000      }
    1010  /*
    1020   * TPGETRPLY(応答を受信する)
    1030   */
    1040      rc = tpgetrply(&cd, (char **) &hptr, &hlen, 0);
    1050      if(rc != 0){
    1060          if(tperrno == TPESVCFAIL){
    1070             werrmsg = (struct errmsg *) hptr ;
    1080             printf("%s ERROR CODE = %d USER CODE = %d\n",
    1090                     werrmsg->errmessage, tperrno, tpurcode);
    1100             goto PROG_END ;
    1110          }else{
    1120             printf("宿泊施設空状況検索サービスに失敗しました。 \
    1130                     ERROR CODE = %d", tperrno);
    1140             goto PROG_END;
    1150          }
    1160      }
    1170      printf("宿泊施設空状況検索サービスの応答受信に成功しました。\n");
    1180      if(hptr->status == 1){
    1190          printf("宿泊施設空き状況 : 満室です。 \n");
    1200      } else {
    1210          printf("宿泊施設空き状況 : 空室があります。 \n");
    1220      }
    1230  /*
    1240   * 型付きバッファの解放
    1250   */
    1260      tpfree((char *) hptr);
    1270      tpfree((char *) pptr);
    1280  /*
    1290   * RPC-CLOSE(UAPの終了)
    1300   */
    1310      PROG_END:
    1320      dc_rpc_close(DCNOFLAGS);
    1330      printf("またのご利用をお待ちしています。\n");
    1340      exit(0);
    1350  }
  • ユーザサービス定義の例

    リクエスト/レスポンス型サービスの例題で示すSUPのユーザサービス定義例を次に示します。

      10  #ユーザサービス定義の例(rrsupファイル)
      20  set  module              = "rrsup"
      30  set  receive_from        = none
      40  set  trn_expiration_time = 180
      50  set  trn_expiration_time_suspend = Y
      60  set  xat_osi_usr = Y

(e) SPPの例

  • XATMIインタフェース定義の例

    リクエスト/レスポンス型サービスの例題で示すSPPのXATMIインタフェース定義を次に示します。

      10  /* XATMIインタフェース定義の例(rrspp.defファイル)*/
      20  X_COMMON hotel {
      30      long   date;
      40      char   place[128];
      50      char   hname[128];
      60      long   status;
      70  };
      80  X_COMMON plane {
      90      long   date;
     100      char   dest[128];
     110      long   departure;
     120      long   status;
     130  };
     140  X_COMMON errmsg {
     150      char   errmessage[128];
     160  };
     170  service shotel(X_COMMON hotel) ;
     180  service splane(X_COMMON plane) ;
  • SPPのコーディング例(メイン関数)

    リクエスト/レスポンス型サービスの例題で示すSPPのコーディング例(メイン関数)を次に示します。

      10  /* SPPのメイン関数例(rrspp.cファイル)*/
      20  #include <stdio.h>
      30  #include <stdlib.h>
      40  #include <dcrpc.h>
      50  #include <xatmi.h>
      60  #include <dcadm.h>
      70  /*
      80   * XATMIスタブヘッダファイル
      90   */
     100  #include "rrspp_stbx.h"
     110  main()
     120  {
     130  /*
     140   * 変数の定義
     150   */
     160     int rc;
     170  /*
     180   * RPC-OPEN(UAPの開始)
     190   */
     200      rc = dc_rpc_open(DCNOFLAGS);
     210      if(rc != DC_OK){
     220          printf("dc_rpc_openに失敗しました。\
     230                  ERROR CODE = %d \n", rc);
     240          goto PROG_END;
     250      }
     260  /*
     270   * RPC-MAINLOOP(SPPのサービス開始)
     280   */
     290      rc = dc_rpc_mainloop(DCNOFLAGS);
     300      if(rc != DC_OK){
     310          printf("dc_rpc_mainloopに失敗しました。\
     320                  ERROR CODE = %d \n", rc);
     330      }
     340  /*
     350   * RPC-CLOSE(UAPの終了)
     360   */
     370  PROG_END:
     380      dc_rpc_close(DCNOFLAGS);
     390      exit(0);
     400  }
  • SPPのコーディング例(サービス関数)

    リクエスト/レスポンス型サービスの例題で示すSPPのコーディング例(サービス関数)を次に示します。

      10  /* SPPのサービス関数例(rrsvc.cファイル)*/
      20  #include <stdio.h>
      30  #include <dcrpc.h>
      40  #include <xatmi.h>
      50  #include <dcadm.h>
      60  /*
      70   * XATMIスタブヘッダファイル
      80   */
      90  #include "rrspp_stbx.h"
     100  void shotel(svcinfo)
     110  TPSVCINFO *svcinfo;
     120  {
     130  /*
     140   * 変数の定義
     150   */
     160      struct hotel *hptr;
     170    
     180      hptr = (struct hotel *) svcinfo->data;
     190      /* このサービスは空き状況を検索して,満室ならば status = 1 ,
     200       * 空室があれば status = 0,エラーが起こったときは,メッセージを返します。
     210       * ここでは,検索した結果,満室だったとします。*/
     220      hptr->status = 1 ;
     230      tpreturn(TPSUCCESS, 0, (char *)hptr, 0, 0);
     240      return ; /* OpenTP1の場合はtpreturn後にreturnの発行が必要です。 */
     250  }
     260  void splane(svcinfo)
     270  TPSVCINFO *svcinfo;
     280  {
     290      struct plane *pptr;
     300      pptr = (struct plane *) svcinfo->data;
     310      /* このサービスは空き状況を検索して,満席ならば status = 1, 
     320       * 空席があれば status = 0 ,エラーが起こったときは,メッセージを返します。
     330       * ここでは,検索した結果,満席だったとします。*/
     340      pptr->status = 1 ;
     350      tpreturn(TPSUCCESS, 0, (char *)pptr, 0, 0);
     360      return ;
     370  }
  • ユーザサービス定義の例

    リクエスト/レスポンス型サービスの例題で示すSPPのユーザサービス定義例を次に示します。

      10  #ユーザサービス定義の例(rrsppファイル)
      20  set    service_group      = "rrspp_svg"
      30  set    module             = "rrspp"
      40  set    service            = "SVHOTEL=shotel","SVPLANE=splane"
      50  set    trn_expiration_time = 180
      60  set    trn_expiration_time_suspend = Y
      70  set    server_type = "xatmi"
      80  set    xat_osi_usr = Y

(2) 会話型サービスの通信の例

(a) 処理の概要

ここで示す例題の処理概要を,次に説明します。

[説明]acctreq構造体の構造を持つ型付きバッファでサービス関数を起動します。acctreqのメンバは口座番号の上限と下限を示します。サービス関数では,この範囲にある口座データをacctdata構造体の構造を持つ型付きバッファに設定して,会話のオリジネータに送信します。

(b) UAPの構成

例題のUAPの構成を次の図に示します。

図7‒5 会話型サービスの通信形態

[図データ]

(c) 通信に使う型付きバッファ

通信に使う型付きバッファの構造体を次に示します。

  • サービス関数起動時のデータ

    struct acctreq{
      DCLONG upper_no;
      DCLONG lower_no;
    }
  • 会話型サービスの通信をするときのデータ

    struct acctdata{
      DCLONG acct_no;
      char name[128];
      short amount;
      char dc_dummy0[2];
    }

(d) SUPの例

  • XATMIインタフェース定義の例

    会話型サービスの例題で示すSUPのXATMIインタフェース定義を次に示します。

      10  /* SUPのXATMIインタフェース定義の例(convsup.defファイル)*/
      20  called_servers = { "convspp.def" };
  • SUPのコーディング例

    会話型サービスの例題で示すSUPのコーディング例を次に示します。

      10  /* SUPのコーディング例(convsup.cファイル)*/
      20  #include <stdio.h>
      30  #include <stdlib.h>
      40  #include <dcrpc.h>
      50  #include <xatmi.h>
      60  #include <tx.h>
      70  #include <dcadm.h>
      80  /*
      90   * XATMIスタブヘッダファイル
     100   */
     110  #include "convsup_stbx.h"
     120  main()
     130  {
     140  /*
     150   * 変数の定義
     160   */
     170      struct   acctreq  *rptr; 
     180      struct   acctdata *dptr; 
     190      long     wlen;
     200      int      cd;
     210      int      rc;
     220      long     revent; 
     230      long     size = 0 ;
     240  /*
     250   * RPC-OPEN(UAPの開始)
     260   */
     270      rc = dc_rpc_open(DCNOFLAGS);
     280      if(rc != DC_OK){
     290          printf("dc_rpc_openに失敗しました。ERROR CODE = %d \n", rc);
     300          goto PROG_END;
     310      }
     320  /*
     330   * ADM-COMPLETE(ユーザサーバの開始処理完了の報告)
     340   */
     350      rc = dc_adm_complete(DCNOFLAGS);
     360      if(rc != DC_OK){
     370          printf("dc_adm_completeに失敗しました。ERROR CODE = %d \n", rc);
     380          goto PROG_END;
     390      }
     400  /*
     410   * TPALLOC(型付きバッファの確保)
     420   */
     430    /*サーチする口座番号の上限,下限の設定用*/  
     440      rptr = (struct acctreq *)tpalloc(X_COMMON, "acctreq", 0);
     450  
     460      if(rptr == NULL){
     470          printf("tpallocに失敗しました。ERROR CODE = %d \n", tperrno);
     480          goto PROG_END;
     490      }
     500    /*サーチ結果の口座データ用*/  
     510      dptr = (struct acctdata *)tpalloc(X_COMMON, "acctdata", 0) ;
     520      if(dptr == NULL){
     530          printf("tpallocに失敗しました。ERROR CODE = %d \n", tperrno);
     540          goto PROG_END;
     550      }
     560  /*
     570   * データの設定
     580   * サーチする範囲を指定
     590   */
     600      rptr->lower_no = 10000000L;
     610      rptr->upper_no = 20000000L;
     620   /* トランザクション開始  */
     630      tx_begin() ;
     640  /*
     650   * TPCONNECT(会話サービスの呼び出し)
     660   * INQUIRYを呼ぶ。
     670   */
     680      cd = tpconnect("INQUIRY", (char *) rptr, 0, TPRECVONLY);
     690      if(cd == -1){
     700          printf("tpconnectに失敗しました。ERROR CODE = %d \n", tperrno);
     710          goto PROG_END;
     720      }
     730  /*
     740   * エラーが起こるまで(イベントの発生も含む),
     750   * TPRECV(メッセージを受信)
     760   */
     770      while(rc != -1){
     780          rc = tprecv(cd, (char **) &dptr, &wlen, 0, &revent);
     790          /*
     800           *エラーが起こっていなければ,
     810           *受信した口座情報を出力する。
     820           */
     830          if(rc != -1) {
     840              printf("サービスから口座情報を受信しました。\n");
     850              printf("口座番号 = %d \n", dptr->acct_no);
     860              printf("名前 = %s \n", dptr->name);
     870              printf("預金 = %d \n", dptr->amount);
     880          }
     890      }
     900  /*
     910   * サービスの結果の出力
     920   */
     930      if(tperrno == TPEEVENT){
     940          if(revent == TPEV_SVCSUCC){
     950          /* サービスは成功した。*/
     960              printf("サービスは成功しました。\n");
     970              /* トランザクションのコミット */
     980              tx_commit() ;
     990          }else{
    1000              printf("何らかのイベントが発生しています。revent = %d\n", 
    1010              revent);
    1020              /* トランザクションのロールバック*/
    1030              tx_rollback() ;
    1040          }
    1050    }
    1060  /*
    1070   * 型付きバッファの解放
    1080   */
    1090      tpfree((char *) rptr);
    1100      tpfree((char *) dptr);
    1110  /*
    1120   * RPC-CLOSE(UAPの終了)
    1130   */
    1140      PROG_END:
    1150      dc_rpc_close(DCNOFLAGS);
    1160      exit(0);
    1170  }
  • ユーザサービス定義の例

    会話型サービスの例題で示すSUPのユーザサービス定義例を次に示します。

      10  #ユーザサービス定義の例(convsupファイル)
      20  set module              = "convsup"         #実行形式ファイル名
      30  set watch_time          = 180               #最大応答待ち時間
      40  set receive_from        = none              #受信方法
      50  set trn_expiration_time = 180
      60                           #トランザクションブランチ限界経過時間
      70  set trn_expiration_time_suspend = Y         #必ず Y を指定

(e) SPPの例

  • XATMIインタフェース定義の例

    会話型サービスの例題で示すSPPのXATMIインタフェース定義を次に示します。

      10  /* SPPのXATMIインタフェース定義の例(convspp.defファイル)*/
      20  X_COMMON acctreq {
      30      long   upper_no;
      40      long   lower_no;
      50  };
      60  X_COMMON acctdata {
      70      long   acct_no;
      80      char   name[128];
      90      short  amount;
     100  };
     110  service inquiry(X_COMMON acctreq) ;
  • SPPのコーディング例(メイン関数)

    会話型サービスの例題で示すSPPのコーディング例(メイン関数)を次に示します。

      10  /* SPPのメイン関数例(convspp.cファイル)*/
      20  #include <stdio.h>
      30  #include <stdlib.h>
      40  #include <dcrpc.h>
      50  #include <xatmi.h>
      60  #include <dcadm.h>
      70  /*
      80   * XATMIスタブヘッダファイル
      90   */
     100  #include "convspp_stbx.h"
     110  main()
     120  {
     130  /*
     140   * 変数の定義
     150   */
     160      int rc;
     170  /*
     180   * RPC-OPEN(UAPの開始)
     190   */
     200      rc = dc_rpc_open(DCNOFLAGS);
     210      if(rc != DC_OK){
     220          printf("dc_rpc_openに失敗しました。ERROR CODE = %d \n", rc);
     230          goto PROG_END;
     240      }
     250    
     260  /*
     270   * RPC-MAINLOOP(SPPのサービス開始)
     280   */
     290      rc = dc_rpc_mainloop(DCNOFLAGS);
     300      if(rc != DC_OK){
     310          printf("dc_rpc_mainloopに失敗しました。ERROR CODE = %d \n",rc);
     320      }
     330  /*
     340   * RPC-CLOSE(UAPの終了)
     350   */
     360      PROG_END:
     370      dc_rpc_close(DCNOFLAGS);
     380      exit(0);
     390  }
  • SPPのコーディング例(サービス関数)

    会話型サービスの例題で示すSPPのコーディング例(サービス関数)を次に示します。

      10  /* SPPのサービス関数例(convsvc.cファイル)*/
      20  #include <stdio.h>
      30  #include <stdlib.h>
      40  #include <string.h>
      50  #include <dcrpc.h>
      60  #include <xatmi.h>
      70  #include <dcadm.h>
      80  /*
      90   * XATMIスタブヘッダファイル
     100   */
     110  #include "convspp_stbx.h"
     120  /*
     130   * DEPOSITSVC  サービス関数
     140   * tpconnect()によって口座番号の上限,下限を受取り
     150   * その範囲にある口座の情報を送信する。
     160   */
     170  void inquiry(svcinfo)
     180  TPSVCINFO *svcinfo;
     190  {
     200  /*
     210   * 変数の定義
     220   */
     230      struct   acctreq  *rptr;
     240      struct   acctdata *dptr;
     250      char     type[9];
     260      char     subtype[17];
     270      long     revent, rval;
     280      int      size;
     290  /*
     300   * サービス要求が受け付けられた
     310   */
     320      rptr = (struct acctreq *) svcinfo->data;
     330  /*
     340   * オリジネータに返すデータのtypedバッファの確保
     350   */
     360      dptr = (struct acctdata *)tpalloc("X_COMMON", "acctdata", 0);
     370      if(dptr == NULL){
     380          printf("tpallocでエラーが起こりました。tperrno = %d \n",
     390                 tperrno);
     400          abort();
     410      }
     420  /*
     430   * ユーザ処理
     440   * データファイルを検索して口座番号が範囲内の口座情報を返す。
     450   * ここでは2件見つかったこととしてデータを送信する。
     460   */
     470      
     480      dptr->acct_no = 10000001L;
     490      strcpy(dptr->name, "Hitachi Hanako");
     500      dptr->amount = 20000;
     510  /*
     520   * TPSEND(メッセージの送信)
     530   */
     540      tpsend(svcinfo->cd, (char *) dptr, 0, 0, &revent);
     550      if(tperrno != -1){
     560          rval = TPSUCCESS;
     570      }else{
     580          rval = TPFAIL;
     590          goto SVC_END;
     600      }
     610      dptr->acct_no = 10000002L;
     620      dptr->amount = 10000;
     630      strcpy(dptr->name, "Hitachi Tarou");
     640  /*
     650   * TPSEND(メッセージの送信)
     660   */
     670      tpsend(svcinfo->cd, (char *) dptr, 0, 0, &revent);
     680      if(tperrno != -1){
     690          rval = TPSUCCESS;
     700      }else{
     710          rval = TPFAIL;
     720          goto SVC_END;
     730      }
     740  SVC_END:
     750      tpreturn(rval, 0, NULL, 0, 0);
     760      return; /* OpenTP1の場合 tpreturn後にreturnが必要です。*/
     770  }
  • ユーザサービス定義の例

    会話型サービスの例題で示すSPPのユーザサービス定義例を次に示します。

      10  # ユーザサービス定義の例(convsppファイル)
      20    set  service_group     = "convspp_svg"     #サービスグループ名
      30    set  module            = "convspp"         #実行形式ファイル名
      40    set  service  = "INQUIRY=inquiry"
      50                              #サービス名=エントリポイント名
      60    set  watch_time        = 180               #最大応答待ち時間
      70    set  trn_expiration_time = 240
      80                           #トランザクションブランチ限界経過時間
      90    set  trn_expiration_time_suspend = Y       #必ず Y を指定
     100    set  server_type = "xatmi"                 #サーバタイプ
     110    set  receive_from = "socket"               #受信方法