目次 前 次


目次

Oracle Tuxedoプログラミングの紹介
Oracle Tuxedo分散アプリケーションのプログラミング
図1-1 分散アプリケーションの例 - オンライン銀行業務システム
通信パラダイム
Oracle Tuxedoクライアント
リスト1-1 リクエスト/レスポンス型クライアントの擬似コード
Oracle Tuxedoサーバー
サーバーの基本的な動作
図1-2 リクエスト/レスポンス型サーバーとサービス・サブルーチンの擬似コード
図1-3 会話型サービス・サブルーチンの擬似コード
リクエスタとしてのサーバー
Oracle Tuxedo API: ATMI
型付きバッファの管理
型付きバッファの概要
関連項目
型付きバッファの割当て
リスト2-1 VIEW型バッファの割当て
リスト2-1 VIEW型バッファの割当て
リスト2-2 FML型バッファの割当て
リスト2-3 CARRAY型バッファの割当て
リスト2-4 STRING型バッファの割当て
リスト2-5 RECORDバッファの割当て
関連項目
データのバッファへの格納
リスト2-6 メッセージ・バッファへのデータの格納 - 例1
リスト2-6 メッセージ・バッファへのデータの格納 - 例1
リスト2-7 メッセージ・バッファへのデータの格納 - 例2
関連項目
型付きバッファのサイズの変更
リスト2-8 バッファのサイズ変更
リスト2-8 バッファのサイズ変更
リスト2-9 tprealloc()のエラーの確認
関連項目
バッファ・タイプの確認
リスト2-10 バッファ・サイズの取得
リスト2-10 バッファ・サイズの取得
関連項目
型付きバッファの解放
リスト2-11 バッファの解放
リスト2-11 バッファの解放
関連項目
VIEW型バッファの使用
VIEW型バッファの環境変数の設定
VIEW記述ファイルの作成
リスト2-12 FML VIEWのVIEW記述ファイル
リスト2-13 非依存型VIEWのVIEW記述ファイル
VIEWコンパイラの実行
リスト2-14 VIEWコンパイラによって生成されるヘッダー・ファイル
関連項目
RECORD型バッファの使用
RECORD型バッファの環境変数の設定
コピーブック・ファイルの作成
RECORD記述ファイルの生成
関連項目
FML型バッファ
FML型バッファの環境変数の設定
フィールド表ファイルの作成
リスト2-15 FML VIEWのフィールド表ファイル
FMLヘッダー・ファイルの作成
リスト2-16 myview.flds.hヘッダー・ファイル
リスト2-16 myview.flds.hヘッダー・ファイル
/* fname fldid *//* ----- ----- */ #define FLOAT1 ((FLDID)24686) /* number: 110 type: float */#define DOUBLE1 ((FLDID)32879) /* number: 111 type: double */#define LONG1 ((FLDID)8304) /* number: 112 type: long */#define SHORT1 ((FLDID)113) /* number: 113 type: short */#define INT1 ((FLDID)8306) /* number: 114 type: long */#define DEC1 ((FLDID)41075) /* number: 115 type: string */#define CHAR1 ((FLDID)16500) /* number: 116 type: char */#define STRING1 ((FLDID)41077) /* number: 117 type: string */#define CARRAY1 ((FLDID)49270) /* number: 118 type: carray */#define   BOOL1#define   SIGNEDCHAR1#define   UNSIGNEDCHAR1#define   WCHAR_T1#define   UNSIGNEDINT1#define   UNSIGNEDLONG1#define   LONGLONG1#define   UNSIGNEDLONGLONG1#define   LONGDOUBLE1#define   STRUCT1
関連項目
XML型バッファとApache Xerces C++パーサーの使用
XML型バッファについて
Apache Xerces C++パーサーについて
XMLパーサーの制御
XMLパーサーでのICUのサポート
XMLパーサーのサンプル・アプリケーション
Xercesスキーマのサンプル
関連項目
XMLデータとFML/FML32バッファ間の変換
オンデマンド変換の使い方
オンデマンド変換を開始する
オンデマンド変換とXercesパーサーXML検証
自動変換の使い方
自動変換を開始する
自動変換とXercesパーサーXML検証
リスト2-17 TXPARSFILE環境変数のサンプル入力
XMLとFML/FML32フィールド型のマッピング
変換の制限事項
関連項目
MBSTRING型バッファの使用
図2-1 MBSTRINGバッファによるエンコード変換の例
図2-1 MBSTRINGバッファによるエンコード変換の例
マルチバイト文字エンコードの制御
図2-2 MBSTRINGバッファの割当ておよび送信
図2-3 MBSTRINGバッファの受信および変換(シート1/2)
図2-3 MBSTRINGバッファの受信および変換(シート2/2)
MBSTRINGを自己記述型にする
実装
安全/危険なエンコード名
マルチバイト文字サポートの制限
マルチバイト文字エンコードでのlibiconvのサポート
関連項目
バッファのカスタマイズ
独自のバッファ・タイプの定義
リスト2-18 デフォルトのバッファ・タイプ・スイッチ
リスト2-18 デフォルトのバッファ・タイプ・スイッチ
リスト2-18 デフォルトのバッファ・タイプ・スイッチ
リスト2-19 バッファ・タイプ構造体
/* * The following definitions are in $TUXDIR/include/tmtypes.h */#define TMTYPELEN ED_TYPELEN #define TMSTYPELEN ED_STYPELENstruct tmtype_sw_t {   char type[TMTYPELEN]; /* type of buffer */   char subtype[TMSTYPELEN]; /* subtype of buffer */   long dfltsize; /* default size of buffer */   /* buffer initialization function pointer */   int (_TMDLLENTRY *initbuf) _((char _TM_FAR *, long));   /* buffer reinitialization function pointer */   int (_TMDLLENTRY *reinitbuf) _((char _TM_FAR *, long));   /* buffer un-initialization function pointer */   int (_TMDLLENTRY *uninitbuf) _((char _TM_FAR *, long));   /* pre-send buffer manipulation func pointer */   long (_TMDLLENTRY *presend) _((char _TM_FAR *, long, long));   /* post-send buffer manipulation func pointer */   void (_TMDLLENTRY *postsend) _((char _TM_FAR *, long, long));   /* post-receive buffer manipulation func pointer*/   long (_TMDLLENTRY *postrecv) _((char _TM_FAR *, long, long));   /* XDR encode/decode function pointer */   long (_TMDLLENTRY *encdec) _((int, char _TM_FAR *, long, char _TM_FAR *, long));   /* routing function pointer */   int (_TMDLLENTRY *route) _((char _TM_FAR *, char _TM_FAR *, char _TM_FAR *,    long, char _TM_FAR *));   /* buffer filtering function pointer */   int (_TMDLLENTRY *filter) _((char _TM_FAR *, long, char _TM_FAR *, long));   /* buffer formatting function pointer */   int (_TMDLLENTRY *format) _((char _TM_FAR *, long, char _TM_FAR *,          char _TM_FAR *, long));   /* process buffer before sending, possibly generating copy */   long (_TMDLLENTRY *presend2) _((char _TM_FAR *, long,          long, char _TM_FAR *, long, long _TM_FAR *));   /* Multibyte code-set encoding conversion function pointer*/   long (_TMDLLENTRY *mbconv) _((char _TM_FAR *, long,         char _TM_FAR *, char _TM_FAR *, long, long _TM_FAR *));   /* this space reserved for future expansion */   void (_TMDLLENTRY *reserved[8]) _((void));};/* * application types switch pointer * always use this pointer when accessing the table */extern struct tmtype_sw_t *tm_typeswp;
スイッチ要素ルーチンのコーディング
リスト2-20 送信前処理スイッチ要素のセマンティクス
tm_typeswへの新しいバッファ・タイプの追加
リスト2-21 新しいタイプのバッファ・スイッチへの追加
リスト2-21 新しいタイプのバッファ・スイッチへの追加
#include <stdio.h>#include <tmtypes.h>/* Customized the buffer type switch */static struct tmtype_sw_t tm_typesw[] = {{"SOUND", /* type */“", /* subtype */50000, /* dfltsize */snd_init, /* initbuf */snd_init, /* reinitbuf */NULL, /* uninitbuf */snd_cmprs, /* presend */snd_uncmprs, /* postsend */snd_uncmprs /* postrecv */},{"FML", /* type */"", /* subtype */1024, /* dfltsize */_finit, /* initbuf */_freinit, /* reinitbuf */_funinit, /* uninitbuf */_fpresend, /* presend */_fpostsend, /* postsend */_fpostrecv, /* postrecv */_fencdec, /* encdec */_froute, /* route */_ffilter, /* filter */_fformat /* format */},{""}};
新しいtm_typeswのコンパイルとリンク
16ビットWindowsプラットフォーム用の新しいtm_typeswのコンパイルとリンク
リスト2-22 Microsoft Visual C++のリスト
リスト2-22 Microsoft Visual C++のリスト
CL -AL -I..\e\|sysinclu -I..\e\|include -Aw -G2swx -Zp -D_TM_WIN -D_TMDLL -Od -c TMTYPESW.CLINK /CO /ALIGN:16 TMTYPESW.OBJ, WBUFT.DLL, NUL, WTUXWS /SE:250 /NOD/NOE LIBW LDLLCEW, WBUFT.DEFRC /30 /T /K WBUFT.DLL
データ変換
プログラミング環境
UBBCONFIG構成ファイルの更新
関連項目
環境変数の設定
関連項目
必要なヘッダー・ファイルのインクルード
アプリケーションの起動と停止
関連項目
クライアントのコーディング
アプリケーションへの参加
リスト4-1 TPINIT型バッファの割当て
リスト4-1 TPINIT型バッファの割当て
関連項目
TPINIT型バッファの機能の使用
クライアントの名前付け
図4-1 クライアントの名前付け
非請求通知の処理
システム・アクセス・モード
リソース・マネージャとの関連付け
クライアント認証
アプリケーションからの分離
クライアントのビルド
注意: Oracle Tuxedoライブラリは自動的にリンクされます。コマンド行にOracle Tuxedoライブラリを指定する必要はありません。
注意: Oracle Tuxedoライブラリは自動的にリンクされます。コマンド行にOracle Tuxedoライブラリを指定する必要はありません。
関連項目
クライアント・プロセスの例
リスト4-2 通常のクライアント・プロセスのパラダイム
リスト4-3 アプリケーションへの参加と分離
サーバーのコーディング
Oracle Tuxedoシステムのmain()
システムで提供されるサーバーおよびサービス
注意: tpsvrinit()とtpsvrdone()を独自にコーディングする場合、この2つのルーチンのデフォルト・バージョンが、それぞれtx_open()とtx_close()を呼び出すことに注意してください。tx_open()ではなくtpopen()を呼び出すtpsvrinit()の新しいバージョンをコーディングする場合は、tpclose()を呼び出すtpsvrdone()もコーディングする必要があります。つまり、この2つの関数が呼び出すオープンとクローズの関数は対になっている必要があります。
注意: tpsvrinit()およびtpsvrdone()の新しいバージョンをコーディングする場合は、これら2つのルーチンのデフォルトのバージョンがtx_open()およびtx_close()をそれぞれ呼び出すことを考慮してください。tx_open()ではなくtpopen()を呼び出すtpsvrinit()の新しいバージョンをコーディングする場合は、tpclose()を呼び出すtpsvrdone()の新しいバージョンもコーディングする必要があります。つまり、open/closeのペア内の両方の関数が同じセットに属する必要があります。
システムで提供されるサーバー: AUTHSVR( )
システムで提供されるサービス: tpsvrinit( )関数
コマンド行オプションの取得
リスト5-1 tpsvrinit()を使用したコマンド行オプションの取得
リソース・マネージャのオープン
リスト5-2 tpsvrinit()を使用したリソース・マネージャのオープン
システムで提供されるサービス: tpsvrdone( )関数
リスト5-3 tpsvrdone()を使用したリソース・マネージャのクローズ
リスト5-3 tpsvrdone()を使用したリソース・マネージャのクローズ
voidtpsvrdone(){      /* Close the database */      if(tpclose() == -1)           (void)userlog("tpsvrdone: failed to close database: ");           switch (tperrno) {                   case TPESYSTEM:                          (void)userlog("BEA TUXEDO error\n");                          break;                   case TPEOS:                          (void)userlog("Unix error %d\n",Uunixerr);                          break;                   case TPEPROTO:                          (void)userlog("Called in improper context\n");                          break;                   case TPERMERR:                          (void)userlog("RM failure\n");                          break;          }           return;    }    return;}
サーバーのコーディングのためのガイドライン
サービスの定義
リスト5-4 一般的なサービス定義
リスト5-4 一般的なサービス定義
例: バッファ・タイプの確認
リスト5-5 バッファ・タイプの確認
リスト5-5 バッファ・タイプの確認
#define TMTYPERR 1 /* return code indicating tptypes failed */#define INVALMTY 2 /* return code indicating invalid message type */ voidABAL(transb) TPSVCINFO *transb; {   struct aud *transv; /* view message */   FBFR *transf; /* fielded buffer message */   int repc; /* tpgetrply return code */   char typ[TMTYPELEN+1], subtyp[TMSTYPELEN+1]; /* type, subtype of message */   char *retstr; /* return string if tptypes fails */ /* find out what type of buffer sent */    if (tptypes((char *)transb->data, typ, subtyp) == -1) {      retstr=tpalloc("STRING", NULL, 100);      (void)sprintf(retstr,      "Message garbled; tptypes cannot tell what type message\n");      tpreturn(TPFAIL, TMTYPERR, retstr, 100, 0);   }/* Determine method of processing service request based on type */   if (strcmp(typ, "FML") == 0) {      transf = (FBFR *)transb->data;... code to do abal service for fielded buffer ... tpreturn succeeds and sends FML buffer in reply   }   else if (strcmp(typ, "VIEW") == 0 && strcmp(subtyp, "aud") == 0) {      transv = (struct aud *)transb->data;... code to do abal service for aud struct ... tpreturn succeeds and sends aud view buffer in reply   }   else {      retstr=tpalloc("STRING", NULL, 100);      (void)sprintf(retstr,      "Message garbled; is neither FML buffer nor aud view\n");      tpreturn(TPFAIL, INVALMTY, retstr, 100, 0);   }}
例: サービス・リクエストの優先度の確認
リスト5-6 受信したリクエストの優先度の確認
リスト5-6 受信したリクエストの優先度の確認
#include <stdio.h>#include "atmi.h" char *roundrobin(); PRINTER(pbuf) TPSVCINFO *pbuf; /* print buffer */ {char prname[20], ocmd[30]; /* printer name, output command */long rlen; /* return buffer length */int prio; /* priority of request */FILE *lp_pipe; /* pipe file pointer */ prio=tpgprio();if (prio <= 20)   (void)strcpy(prname,"bigjobs"); /* send low priority (verbose)                                     jobs to big comp. center                                     laser printer where operator                                     sorts output and puts it                                     in a bin */else if (prio <= 60)   (void)strcpy(prname,roundrobin()); /* assign printer on a                                        rotating basis to one of                                        many local small laser printers                                        where output can be picked                                        up immediately; roundrobin() cycles                                        through list of printers */else   (void)strcpy(prname,"hispeed");                                   /* assign job to high-speed laser                                      printer; reserved for those who                                      need verbose output on a daily,                                      frequent basis */ (void)sprintf(ocmd, "lp -d%s", prname); /* output lp(1) command */lp_pipe = popen(ocmd, "w"); /* create pipe to command */(void)fprintf(lp_pipe, "%s", pbuf->data); /* print output there */(void)pclose(lp_pipe); /* close pipe */ if ((pbuf->flags & TPNOREPLY))   tpreturn(TPSUCCESS, 0, NULL, 0, 0);rlen = strlen(prname) + 1;pbuf->data = tprealloc(pbuf->data, rlen); /* ensure enough space for name */(void)strcpy(pbuf->data, prname);tpreturn(TPSUCCESS, 0, pbuf->data, rlen, 0); char *roundrobin() {static char *printers[] = {"printer1", "printer2", "printer3", "printer4"};static int p = 0; if (p > 3)   p=0;return(printers[p++]);}
サービス・ルーチンの終了
応答の送信
リスト5-7 tpreturn()関数
リスト5-7 tpreturn()関数
#include <stdio.h> /* UNIX */#include <string.h> /* UNIX */#include "fml.h" /* BEA Tuxedo System */#include "atmi.h" /* BEA Tuxedo System */#include "Usysflds.h" /* BEA Tuxedo System */#include "userlog.h" /* BEA Tuxedo System */#include "bank.h" /* BANKING #defines */#include "bank.flds.h" /* bankdb fields */ /* * Service to transfer an amount from a debit account to a credit * account */ void#ifdef __STDC__TRANSFER(TPSVCINFO *transb) #else TRANSFER(transb)TPSVCINFO *transb;#endif {   FBFR *transf; /* fielded buffer of decoded message */   long db_id, cr_id; /* from/to account id’s */   float db_bal, cr_bal; /* from/to account balances */   float tamt; /* amount of the transfer */   FBFR *reqfb; /* fielded buffer for request message*/   int reqlen; /* length of fielded buffer */   char t_amts[BALSTR]; /* string for transfer amount */   char db_amts[BALSTR]; /* string for debit account balance */   char cr_amts[BALSTR]; /* string for credit account balance */ /* Set pointr to TPSVCINFO data buffer */transf = (FBFR *)transb->data; /* Get debit (db_id) and credit (cr_id) account IDs */ /* must have valid debit account number */if (((db_id = Fvall(transf, ACCOUNT_ID, 0)) < MINACCT) || (db_id > MAXACCT)) {   (void)Fchg(transf, STATLIN, 0,"Invalid debit account number",(FLDLEN)0);   tpreturn(TPFAIL, 0, transb->data, 0L, 0);}/* must have valid credit account number */if ((cr_id = Fvall(transf, ACCOUNT_ID, 1)) < MINACCT || cr_id > MAXACCT) {   (void)Fchg(transf,STATLIN, 0,"Invalid credit account number",(FLDLEN)0);   tpreturn(TPFAIL, 0, transb->data, 0L, 0);} /* get amount to be withdrawn */if (Fget(transf, SAMOUNT, 0, t_amts, < 0) 0 || strcmp(t_amts,"") == 0) {   (void)Fchg(transf, STATLIN, 0, "Invalid amount",(FLDLEN)0);   tpreturn(TPFAIL, 0, transb->data, 0L, 0);}(void)sscanf(t_amts,"%f",tamt); /* must have valid amount to transfer */if (tamt = 0.0) {   (void)Fchg(transf, STATLIN, 0,      "Transfer amount must be greater than $0.00",(FLDLEN)0);    tpreturn(TPFAIL, 0, transb->data, 0L, 0);} /* make withdraw request buffer */if ((reqfb = (FBFR *)tpalloc("FML",NULL,transb->len)) == (FBFR *)NULL) {   (void)userlog("tpalloc failed in transfer\n");   (void)Fchg(transf, STATLIN, 0,      "unable to allocate request buffer", (FLDLEN)0);   tpreturn(TPFAIL, 0, transb->data, 0L, 0);}reqlen = Fsizeof(reqfb); /* put ID in request buffer */(void)Fchg(reqfb,ACCOUNT_ID,0,(char *)&db_id, (FLDLEN)0); /* put amount in request buffer */(void)Fchg(reqfb,SAMOUNT,0,t_amts, (FLDLEN)0); /* increase the priority of withdraw call */if (tpsprio(PRIORITY, 0L) == -1)   (void)userlog("Unable to increase priority of withdraw\n"); if (tpcall("WITHDRAWAL", (char *)reqfb,0, (char **)&reqfb,      (long *)&reqlen,TPSIGRSTRT) == -1) {   (void)Fchg(transf, STATLIN, 0,         "Cannot withdraw from debit account", (FLDLEN)0);   tpfree((char *)reqfb);   tpreturn(TPFAIL, 0,transb->data, 0L, 0);} /* get "debit" balance from return buffer */ (void)strcpy(db_amts, Fvals((FBFR *)reqfb,SBALANCE,0));void)sscanf(db_amts,"%f",db_bal);if ((db_amts == NULL) || (db_bal < 0.0)) {   (void)Fchg(transf, STATLIN, 0,         "illegal debit account balance", (FLDLEN)0);   tpfree((char *)reqfb);   tpreturn(TPFAIL, 0, transb->data, 0L, 0);} /* put deposit account ID in request buffer */(void)Fchg(reqfb,ACCOUNT_ID,0,(char *)&cr_id, (FLDLEN)0); /* put transfer amount in request buffer */(void)Fchg(reqfb,SAMOUNT,0,t_amts, (FLDLEN)0); /* Up the priority of deposit call */if (tpsprio(PRIORITY, 0L) == -1) (void)userlog("Unable to increase priority of deposit\n"); /* Do a tpcall to deposit to second account */if (tpcall("DEPOSIT", (char *)reqfb, 0, (char **)&reqfb,        (long *)&reqlen, TPSIGRSTRT) == -1) {   (void)Fchg(transf, STATLIN, 0,           "Cannot deposit into credit account", (FLDLEN)0);   tpfree((char *)reqfb);   tpreturn(TPFAIL, 0,transb->data, 0L, 0);} /* get "credit" balance from return buffer */ (void)strcpy(cr_amts, Fvals((FBFR *)reqfb,SBALANCE,0));(void)sscanf(cr_amts,"%f",&cr_bal);if ((cr_amts == NULL) || (cr_bal 0.0)) {   (void)Fchg(transf, STATLIN, 0,         "Illegal credit account balance", (FLDLEN)0);    tpreturn(TPFAIL, 0, transb->data, 0L, 0);} /* set buffer for successful return */(void)Fchg(transf, FORMNAM, 0, "CTRANSFER", (FLDLEN)0);(void)Fchg(transf, SAMOUNT, 0, Fvals(reqfb,SAMOUNT,0), (FLDLEN)0);(void)Fchg(transf, STATLIN, 0, "", (FLDLEN)0);(void)Fchg(transf, SBALANCE, 0, db_amts, (FLDLEN)0);(void)Fchg(transf, SBALANCE, 1, cr_amts, (FLDLEN)0);tpfree((char *)reqfb);tpreturn(TPSUCCESS, 0,transb->data, 0L, 0);}
記述子の無効化
リスト5-8 タイムアウト後の応答の無効化
リクエストの転送
図5-1 リクエストの転送
図5-1 リクエストの転送
図5-1 リクエストの転送
リスト5-9 tpforward()関数
.../* set pointer to TPSVCINFO data buffer */ transf = (FBFR *)transb->data;.../* Insert new account record into ACCOUNT*/ account_id = ++last_acct; /* get new account number */tlr_bal = 0.0; /* temporary balance of 0 */ EXEC SQL insert into ACCOUNT (ACCOUNT_ID, BRANCH_ID, BALANCE,ACCT_TYPE, LAST_NAME, FIRST_NAME, MID_INIT, ADDRESS, PHONE) values(:account_id, :branch_id, :tlr_bal, :acct_type, :last_name,      :first_name, :mid_init, :address, :phone);if (SQLCODE != SQL_OK) { /* Failure to insert */      (void)Fchg(transf, STATLIN, 0,          "Cannot update ACCOUNT", (FLDLEN)0);      tpreturn(TPFAIL, 0, transb->data, 0L, 0);} /* Update branch record with new LAST_ACCT */ EXEC SQL update BRANCH set LAST_ACCT = :last_acct where BRANCH_ID = :branch_id;if (SQLCODE != SQL_OK) { /* Failure to update */       (void)Fchg(transf, STATLIN, 0,           "Cannot update BRANCH", (FLDLEN)0);       tpreturn(TPFAIL, 0, transb->data, 0L, 0);}/* up the priority of the deposit call */if (tpsprio(PRIORITY, 0L) == -1)     (void)userlog("Unable to increase priority of deposit\n"); /* tpforward same buffer to deposit service to add initial balance */tpforward("DEPOSIT", transb->data, 0L, 0);
サービスの通知と通知解除
サービスの通知
tpadvertise()
tpadvertisex()
サービスの通知解除
例:サービスの動的な宣言と通知解除
リスト5-10 動的な公開と通知解除
サーバーのビルド
注意: Oracle Tuxedoライブラリは自動的にリンクされます。コマンド行にOracle Tuxedoライブラリ名を指定する必要はありません。
注意: Oracle Tuxedoライブラリは自動的にリンクされます。コマンド行にOracle Tuxedoライブラリ名を指定する必要はありません。
関連項目
C++コンパイラの使用
サービス関数の宣言
コンストラクタとデストラクタの使用
クライアントおよびサーバーへのリクエスト/レスポンスのコーディング
リクエスト/レスポンス通信の概要
図6-1 オンライン銀行業務でのリクエスト/レスポンス通信
同期メッセージの送信
例: リクエスト・メッセージと応答メッセージに同じバッファの使用
リスト6-1 リクエスト・メッセージと応答メッセージに同じバッファの使用
例: 応答バッファのサイズ変更の確認
リスト6-2 応答バッファのサイズ変更の確認
例: TPSIGRSTRTフラグを設定した同期メッセージの送信
リスト6-3 TPSIGRSTRTフラグを設定した同期メッセージの送信
例: TPNOTRANフラグを設定した同期メッセージの送信
リスト6-4 TPNOTRANフラグを設定した同期メッセージの送信
例: TPNOCHANGEフラグを設定した同期メッセージの送信
リスト6-5 TPNOCHANGEフラグを設定した同期メッセージの送信
非同期メッセージの送信
非同期リクエストの送信
例: TPNOTRANとTPNOREPLYフラグを設定した非同期メッセージの送信
リスト6-6 TPNOTRANとTPNOREPLYフラグを設定した非同期メッセージの送信
例: 非同期リクエストの送信
リスト6-7 非同期リクエストの送信
非同期応答の受信
メッセージの優先度の設定および取得
メッセージの優先度の設定
リスト6-8 リクエスト・メッセージの優先度の設定
メッセージの優先度の取得
リスト6-9 送信後のリクエストの優先度の確認
会話型クライアントおよびサーバーのコーディング
会話型通信の概要
図7-1 銀行業務オンライン・アプリケーションでの会話型通信の例
アプリケーションへの参加
接続の確立
リスト7-1 会話型接続の確立
メッセージの送受信
メッセージの送信
リスト7-2 会話モードでのデータ送信
メッセージの受信
リスト7-3 会話型でのデータ受信
会話の終了
例: 単純な会話の終了
図7-2 正常に終了する単純な会話
例: 階層構造の会話の終了
図7-3 接続の階層構造
会話の切断
会話型のクライアントおよびサーバーのビルド
会話型通信イベントの理解
イベント・ベースのクライアントおよびサーバーのコーディング
イベントの概要
非請求イベント
ブローカ・イベント
通知処理
イベント・ブローカ・サーバー
システム定義のイベント
イベント・ブローカ・プログラミング・インタフェース
非請求メッセージ・ハンドラの定義
非請求メッセージの送信
名前によるメッセージのブロードキャスト
inttpbroadcast(char *lmid, char *usrname, char *cltname, char *data, long len, long flags)
リスト8-1 tpbroadcast()の使用
識別子によるメッセージのブロードキャスト
非請求メッセージの確認
イベントのサブスクライブ
long handletpsubscribe (char *eventexpr, char *filter, TPEVCTL *ctl, long flags)
long handletpsubscribe (char *eventexpr, char *filter, TPEVCTL *ctl, long flags)
非請求メッセージを使用した通知
サービス呼び出しまたは信頼できるキューを使用した通知
イベントに対するサブスクリプションの削除
イベントのポスト
リスト8-2 tppost()を使用したイベントのポスト
リスト8-2 tppost()を使用したイベントのポスト
.../* Event logic related */static float evt_thresh = 10000.00 ; /* default for event threshold */static char emsg[200] ; /* used by event posting logic */.../* Post a BANK_TLR_WITHDRAWAL event ? */if (amt < evt_thresh) {     /* no event to post */     tpreturn(TPSUCCESS, 0,transb->data , 0L, 0);}/* prepare to post the event */if ((Fchg (transf, EVENT_NAME, 0, "BANK_TLR_WITHDRAWAL", (FLDLEN)0) == -1) ||(Fchg (transf, EVENT_TIME, 0, gettime(), (FLDLEN)0) == -1) ||(Fchg (transf, AMOUNT, 0, (char *)&amt, (FLDLEN)0) == -1)) {     (void)sprintf (emsg, "Fchg failed for event fields: %s",     Fstrerror(Ferror)) ;}/* post the event */else if (tppost ("BANK_TLR_WITHDRAWAL", /* event name */(char *)transf, /* data */0L, /* len */TPNOTRAN | TPSIGRSTRT) == -1) {/* If event broker is not reachable, ignore the error */     if (tperrno != TPENOENT)     (void)sprintf (emsg, "tppost failed: %s", tpstrerror (tperrno));}
イベントのサブスクリプションの例
リスト8-3 tpsubscribe()を使用したイベントのサブスクライブ
リスト8-3 tpsubscribe()を使用したイベントのサブスクライブ
.../* Event Subscription handles */static long sub_ev_largeamt = 0L ;.../* Preset default for option 'w' - watchdog threshold */(void)strcpy (amt_expr, "AMOUNT > 10000.00") ;.../* * Subscribe to the events generated * when a "large" amount is transacted. */evctl.flags = TPEVSERVICE ;(void)strcpy (evctl.name1, "WATCHDOG") ;/* Subscribe */sub_ev_largeamt = tpsubscribe ("BANK_TLR_.*",amt_expr,&evctl,TPSIGRSTRT) ;if (sub_ev_largeamt == -1L) {     (void)userlog ("ERROR: tpsubscribe for event BANK_TLR_.* failed: %s",     tpstrerror(tperrno)) ;     return -1 ;}...{/* Unsubscribe to the subscribed events */if (tpunsubscribe (sub_ev_largeamt, TPSIGRSTRT) == -1)    (void)userlog ("ERROR: tpunsubscribe to event BANK_TLR_.* failed: %s",    tpstrerror(tperrno)) ;    return ;}/** Service called when a BANK_TLR_.* event is posted.*/void#if defined(__STDC__) || defined(__cplusplus)WATCHDOG(TPSVCINFO *transb)#elseWATCHDOG(transb)TPSVCINFO *transb;#endif{FBFR *transf; /* fielded buffer of decoded message *//* Set pointr to TPSVCINFO data buffer */transf = (FBFR *)transb->data;/* Print the log entry to stdout */(void)fprintf (stdout, "%20s|%28s|%8ld|%10.2f\n",Fvals (transf, EVENT_NAME, 0),Fvals (transf, EVENT_TIME, 0),Fvall (transf, ACCOUNT_ID, 0),*( (float *)CFfind (transf, AMOUNT, 0, NULL, FLD_FLOAT)) );/* No data should be returned by the event subscriber's svc routine */tpreturn(TPSUCCESS, 0,NULL, 0L, 0);}
グローバル・トランザクションのコーディング
グローバル・トランザクションとは
トランザクションの開始
リスト9-1 グローバル・トランザクションの定義 - 簡単な例
リスト9-1 グローバル・トランザクションの定義 - 簡単な例
リスト9-2 グローバル・トランザクションの定義 - 詳細な例
#include <stdio.h> /* UNIX */#include <string.h> /* UNIX */#include <atmi.h> /* BEA Tuxedo System */#include <Uunix.h> /* BEA Tuxedo System */#include <userlog.h> /* BEA Tuxedo System */#include "bank.h" /* BANKING #defines */#include "aud.h" /* BANKING view defines */ #define INVI 0 /* account inquiry */#define ACCT 1 /* account inquiry */#define TELL 2 /* teller inquiry */ static int sum_bal _((char *, char *));static long sitelist[NSITE] = SITEREP; /* list of machines to audit */static char pgmname[STATLEN]; /* program name = argv[0] */static char result_str[STATLEN]; /* string to hold results of query */ main(argc, argv)int argc;char *argv[];{        int aud_type=INVI; /* audit type -- invalid unless specified */        int clarg; /* command line arg index from optind */        int c; /* Option character */        int cflgs=0; /* Commit flags, currently unused */        int aflgs=0; /* Abort flags, currently unused */        int nbl=0; /* count of branch list entries */        char svc_name[NAMELEN]; /* service name */        char hdr_type[NAMELEN]; /* heading to appear on output */        int retc; /* return value of sum_bal() */        struct aud *audv; /* pointer to audit buf struct */        int audrl=0; /* audit return length */        long q_branchid; /* branch_id to query */ . . . /* Get Command Line Options and Set Variables */ /* Join application */ if (tpinit((TPINIT *) NULL) == -1) {        (void)userlog("%s: failed to join application\n", pgmname);        exit(1);}/* Start global transaction */if (tpbegin(30, 0) == -1) {        (void)userlog("%s: failed to begin transaction\n", pgmname);        (void)tpterm();        exit(1);}if (nbl == 0) { /* no branch id specified so do a global sum */ retc = sum_bal(svc_name, hdr_type); /* sum_bal routine not shown */ } else {         /* Create buffer and set data pointer */                if ((audv = (struct aud *)tpalloc("VIEW", "aud", sizeof(struct aud)))                == (struct aud *)NULL) {                (void)userlog("audit: unable to allocate space for VIEW\n");                exit(1);        }         /* Prepare aud structure */         audv->b_id = q_branchid;        audv->balance = 0.0;        audv->ermsg[0] = '\0';         /* Do tpcall */         if (tpcall(svc_name,(char *)audv,sizeof(struct aud),           (char **)audv,(long *)audrl,0) == -1){                    (void)fprintf (stderr,"%s service failed\n%s: %s\n",                    svc_name, svc_name, audv->ermsg);                    retc = -1;         }else {                  (void)sprintf(result_str,"Branch %ld %s balance is $%.2f\n",                  audv->b_id, hdr_type, audv->balance);        }                 tpfree((char *)audv);} /* Commit global transaction */ if (retc < 0) /* sum_bal failed so abort */       (void) tpabort(aflgs);else {         if (tpcommit(cflgs) == -1) {                 (void)userlog("%s: failed to commit transaction\n", pgmname);                 (void)tpterm();                 exit(1);        }        /*print out results only when transaction has committed successfully*/        (void)printf("%s",result_str);} /* Leave application */ if (tpterm() == -1) {        (void)userlog("%s: failed to leave application\n", pgmname);        exit(1);}
リスト9-3 トランザクションのタイムアウトの確認
トランザクションの中断と再開
トランザクションの中断
トランザクションの再開
例: トランザクションの中断と再開
リスト9-4 トランザクションの中断と再開
トランザクションの終了
現在のトランザクションのコミット
トランザクションをコミットするための条件
2フェーズ・コミット・プロトコル
コミットの成功条件の選択
コミット条件での妥協点
現在のトランザクションの中断
例: 会話モードによるトランザクションのコミット
図9-1 トランザクション・モードにおける接続階層構造
例: 参加リソースのエラーの確認
リスト9-5 参加リソースの成功/失敗の確認
リスト9-5 参加リソースの成功/失敗の確認
001 #include <stdio.h>002 #include "atmi.h"003004 main()005 {006 char *sbuf, *rbuf;007 long slen, rlen;008 if (tpinit((TPINIT *) NULL) == -1)009 error message, exit program;010 if (tpbegin(30, 0) == -1)011 error message, tpterm, exit program;012 if ((sbuf=tpalloc("STRING", NULL, 100)) == NULL)013 error message, tpabort, tpterm, exit program;014 if ((rbuf=tpalloc("STRING", NULL, 2000)) == NULL)015 error message, tpfree sbuf, tpabort, tpterm, exit program;016 (void)strcpy(sbuf, "REPORT=accrcv DBNAME=accounts");017 slen=strlen(sbuf);018 if (tpcall("REPORT", sbuf, slen, &rbuf, &rlen, 0) == -1) {019 switch(tperrno) {020 case TPESVCERR:021 fprintf(stderr,022 "REPORT service's tpreturn encountered problems\n");023 break;024 case TPESVCFAIL:025 fprintf(stderr,026 "REPORT service TPFAILED with return code of %d\n", tpurcode);027 break;028 case TPEOTYPE:029 fprintf(stderr,030 "REPORT service's reply is not of any known data type\n");031 break;032 default:033 fprintf(stderr,034 "REPORT service failed with error %d\n", tperrno);035 break;036 }037 if (tpabort(0) == -1){038 check for errors;039 }040 }041 else042 if (tpcommit(0) == -1)043 fprintf(stderr, "Transaction failed at commit time\n");044 tpfree(rbuf);045 tpfree(sbuf);046 tpterm();047 exit(0);048 }
グローバル・トランザクションの暗黙的な定義
サービス・ルーチンのトランザクションの暗黙的な定義
XA準拠のサーバー・グループに対するグローバル・トランザクションの定義
トランザクションが開始されたことの確認
リスト9-6 トランザクション・レベルの確認
リスト9-6 トランザクション・レベルの確認
リスト9-6 トランザクション・レベルの確認
001 #define BEGFAIL 3 /* tpurcode setting for return if tpbegin fails */ 002 void003 OPEN_ACCT(transb) 004 TPSVCINFO *transb; 005 { ... other declarations ...006 FBFR *transf; /* fielded buffer of decoded message */007 int dotran; /* checks whether service tpbegin/tpcommit/tpaborts */ 008 /* set pointer to TPSVCINFO data buffer */ 009 transf = (FBFR *)transb->data; 010 /* Test if transaction exists; initiate if no, check if yes */ 011 dotran = 0;012 if (tpgetlev() == 0) {013 dotran = 1;014 if (tpbegin(30, 0) == -1) {015 Fchg(transf, STATLIN, 0,016 "Attempt to tpbegin within service routine failed\n");017 tpreturn(TPFAIL, BEGFAIL, transb->data, 0, 0);018 }019 } . . .
関連項目
マルチスレッドおよびマルチコンテキストATMIアプリケーションのプログラミング
マルチスレッド/マルチコンテキストATMIアプリケーションのプログラミングに対するサポート
マルチスレッドおよびマルチコンテキスト・アプリケーションに関するプラットフォーム固有の検討事項
関連項目
マルチスレッド/マルチコンテキストATMIアプリケーションの計画と設計
マルチスレッドおよびマルチコンテキストとは
マルチスレッドとは
図10-1 マルチスレッド・プロセスの例
図10-2 1つのサーバー・プロセスによる複数のサービス・スレッドのディスパッチ
マルチコンテキストとは
図10-3 2つのドメイン内でのマルチコンテキスト・プロセス
マルチスレッド・アプリケーションまたはマルチコンテキスト・アプリケーションの監査
関連項目
マルチスレッド/マルチコンテキストATMIアプリケーションの利点と問題点
マルチスレッド/マルチコンテキストATMIアプリケーションの利点
マルチスレッド/マルチコンテキストATMIアプリケーションの問題点
関連項目
クライアントでのマルチスレッドとマルチコンテキストの動作
起動フェーズ
クライアント・スレッドの複数コンテキストへの参加
クライアント・スレッドの既存のコンテキストへの切り替わり
作業フェーズ
サービス・リクエスト
サービス・リクエストに対する応答
トランザクション
非請求メッセージ
ユーザー・ログで保持されるスレッド固有の情報
完了フェーズ
関連項目
ATMIサーバーでのサーバー・ディスパッチ・スレッドのマルチスレッドとマルチコンテキストの動作
起動フェーズ
作業フェーズ
サーバー・ディスパッチ・スレッドの使用方法
BBLによるシステム・プロセスの正常性チェック
システムで保持されるサーバー・スレッドの統計
ユーザー・ログで保持されるスレッド固有の情報
完了フェーズ
関連項目
ATMIサーバーのアプリケーション生成スレッドのマルチスレッドとマルチコンテキストの動作
起動フェーズ
作業フェーズ
注意: アプリケーション生成のサーバー・スレッドは、tpreturn()およびtpforward()を呼び出すことはできません。
注意: アプリケーション生成のサーバー・スレッドは、tpreturn()およびtpforward()を呼び出すことはできません。
ユーザー・ログで保持されるスレッド固有の情報
完了フェーズ
関連項目
マルチスレッドおよびマルチコンテキストATMIアプリケーションの設計上の検討事項
環境の要件
設計の要件
マルチスレッドやマルチコンテキストに適するアプリケーションのタスク
必要なアプリケーションと接続の数
同期に関する検討事項
アプリケーションの移植
最適なスレッド・モデル
ワークステーション・クライアントの相互運用性に関する制約
関連項目
マルチスレッドおよびマルチコンテキストATMIアプリケーションの実装
マルチスレッド/マルチコンテキストATMIアプリケーションのプログラミング開始前のガイドライン
マルチスレッドATMIアプリケーションに必要な条件
マルチスレッド・アプリケーションのプログラミングでの一般的な検討事項
同時実行性に関する検討事項
関連項目
ATMIクライアントでマルチコンテキストを使用するためのコーディング
コンテキストの属性
初期化時のマルチコンテキストの設定
リスト10-1 クライアントのマルチコンテキスト・アプリケーションへの参加のサンプル・コード
マルチコンテキストATMIクライアントのセキュリティの実装
ATMIクライアント終了前のスレッドの同期
コンテキストの切替え
リスト10-2 クライアントでのコンテキストの切替え
リスト10-2 クライアントでのコンテキストの切替え
#include <stdio.h>#include "atmi.h" /* Oracle Tuxedo header file */#if defined(__STDC__) || defined(__cplusplus)main(int argc, char *argv[])#elsemain(argc, argv)int argc;char *argv[];#endif{          TPINIT * tpinitbuf;       TPCONTEXT_T firstapp_contextID, secondapp_contextID;   /* Assume that TUXCONFIG is initially set to /home/firstapp/TUXCONFIG*/          /*         * Attach to the Oracle Tuxedo system in multicontext mode.        */        tpinitbuf=tpalloc(“TPINIT”, NULL, TPINITNEED(0));   tpinitbuf->flags = TPMULTICONTEXTS;       if (tpinit((TPINIT *) tpinitbuf) == -1) {      (void) fprintf(stderr, "Tpinit failed\n");      exit(1);       }       /*        * Obtain a handle to the current context.        */          tpgetctxt(&firstapp_contextID, 0);          /*        * Use tuxputenv to change the value of TUXCONFIG,        * so we now tpinit to another application.        */        tuxputenv("TUXCONFIG=/home/second_app/TUXCONFIG");        /*        * tpinit to secondapp.        */        if (tpinit((TPINIT *) tpinitbuf) == -1) {                 (void) fprintf(stderr, "Tpinit failed\n");                 exit(1);       }    /*        * Get a handle to the context of secondapp. */       tpgetctxt(&secondapp_contextID, 0);       /*        * Now you can alternate between the two contexts        * using tpsetctxt and the handles you obtained from           * tpgetctxt. You begin with firstapp.        */       tpsetctxt(firstapp_contextID, 0);       /*           * You call services offered by firstapp and then switch        * to secondapp.        */          tpsetctxt(secondapp_contextID, 0);        /*           * You call services offered by secondapp.        * Then you switch back to firstapp.        */          tpsetctxt(firstapp_contextID, 0);       /*           * You call services offered by firstapp. When you have           * finished, you terminate the context for firstapp.        */       tpterm();       /*           * Then you switch back to secondapp.        */       tpsetctxt(secondapp_contextID, 0);       /*           * You call services offered by secondapp. When you have              finished, you terminate the context for secondapp and          end your program.        */       tpterm();       return(0);}
非請求メッセージの処理
マルチスレッド/マルチコンテキストATMIアプリケーションにおけるトランザクションのコーディング規則
関連項目
ATMIサーバーでサーバー・ディスパッチのマルチコンテキストおよびマルチスレッドのスレッドを使用するためのコーディング
コンテキストの属性
マルチコンテキストATMIサーバーでのサーバー・ディスパッチ・スレッドのコーディング規則
ATMIサーバーおよびATMIサーバー・スレッドの初期化と終了
関連項目
ATMIサーバーのアプリケーション生成スレッドでマルチコンテキストを使用するためのコーディング
スレッドの生成
コンテキストへのアプリケーション・スレッドの関連付け
既存のサーバー・ディスパッチ・コンテキストへのアプリケーション・スレッドの関連付け
マルチコンテキスト・サーバーでの既存のサーバー・ディスパッチ・コンテキストにアプリケーション・スレッドを関連付けするためのサンプル・コード
リスト10-3 アプリケーション生成のサーバー・スレッドがサーバー・ディスパッチ・コンテキストで動作するサンプル・コード
アプリケーション生成のコンテキストへのアプリケーション・スレッドの関連付け
コンテキストの属性
アプリケーション生成のコンテキストでのATMIサーバーのアプリケーション生成スレッドのコーディング規則
マルチコンテキスト・サーバーでのアプリケーション生成のサーバー・コンテキストにアプリケーション・スレッドを関連付けするためのサンプル・コード
リスト10-4 アプリケーション生成のサーバー・スレッドがアプリケーション生成のコンテキストで動作するサンプル・コード
関連項目
マルチスレッドATMIクライアントのコーディング
マルチスレッドATMIクライアントのコーディング規則
ATMIクライアントの複数のコンテキストへの初期化
ATMIクライアント・スレッドのコンテキスト状態の変化
図10-4 マルチコンテキスト状態の遷移
マルチスレッド環境での応答の取得
マルチスレッド・マルチコンテキスト環境の環境変数の使用
マルチスレッドATMIクライアントでのコンテキスト単位の関数とデータ構造体
マルチスレッドATMIクライアントでのプロセス単位の関数とデータ構造体
マルチスレッドATMIクライアントでのスレッド単位の関数とデータ構造体
マルチスレッドATMIクライアントのサンプル・コード
リスト10-5 マルチスレッド・クライアントのサンプル・コード
リスト10-5 マルチスレッド・クライアントのサンプル・コード
#include <stdio.h>#include <pthread.h>#include <atmi.h>TPINIT * tpinitbuf;int timeout=60;pthread_t withdrawalthreadid, stockthreadid;TPCONTEXT_T ctxt;void * stackthread(void *);void * withdrawalthread(void *);main(){       tpinitbuf = tpalloc(TPINIT, NULL, TPINITNEED(0));       /*        * This code will perform a transfer, using separate threads for the         * withdrawal and deposit. It will also get the current         * price of Oracle stock from a separate application, and calculate how        * many shares the transferred amount can buy.        */       tpinitbuf->flags = TPMULTICONTEXTS;       /* Fill in the rest of tpinitbuf. */       tpinit(tpinitbuf);       tpgetctxt(&ctxt, 0);       tpbegin(timeout, 0);       pthread_create(&withdrawalthreadid, NULL, withdrawalthread, NULL);       tpcall("DEPOSIT", ...);       /* Wait for the withdrawal thread to complete. */       pthread_join(withdrawalthreadid, NULL);       tpcommit(0);       tpterm();       /* Wait for the stock thread to complete. */       pthread_join(stockthreadid, NULL);       /* Print the results. */       printf("$%9.2f has been transferred \       from your savings account to your checking account.\n", ...);       printf("At the current Oracle stock price of $%8.3f, \       you could purchase %d shares.\n", ...);       exit(0);}void *stockthread(void *arg){     /* The other threads have now called tpinit(), so resetting TUXCONFIG can      * no longer adversely affect them.     */     tuxputenv("TUXCONFIG=/home/users/xyz/stockconf");     tpinitbuf->flags = TPMULTICONTEXTS;     /* Fill in the rest of tpinitbuf. */     tpinit(tpinitbuf);     tpcall("GETSTOCKPRICE", ...);     /* Save the stock price in a variable that can also be accessed in main(). */     tpterm();     return(NULL);}void *withdrawalthread(void *arg){       /* Create a separate thread to get stock prices from a different        * application.        */
     pthread_create(&stockthreadid, NULL, stockthread, NULL);     tpsetctxt(ctxt, 0);     tpcall("WITHDRAWAL", ...);     return(NULL);}
関連項目
マルチスレッドATMIサーバーのコーディング
マルチスレッド/マルチコンテキストATMIアプリケーションのコードのコンパイル
関連項目
マルチスレッド/マルチコンテキストATMIアプリケーションのテスト
マルチスレッド/マルチコンテキストATMIアプリケーションのテスト時の推奨事項
マルチスレッド/マルチコンテキストATMIアプリケーションのトラブルシューティング
tpinit( )のTPMULTICONTEXTSフラグの間違った使用
TPMULTICONTEXTSが設定されていない場合のtpinit()の呼出し
スレッドのスタック・サイズの不足
マルチスレッド/マルチコンテキストATMIアプリケーションのエラー処理
関連項目
エラーの管理
システム・エラー
システム・エラー
中断エラー
Oracle Tuxedoのシステム・エラー
呼出し記述子のエラー
上限値に関するエラー
無効な記述子によるエラー
会話に関するエラー
複製オブジェクトに関するエラー
一般的な通信呼出しのエラー
TPESVCFAILおよびTPESVCERRエラー
TPEBLOCKおよびTPGOTSIGエラー
無効な引数によるエラー
MIBエラー
エントリがないために発生するエラー
オペレーティング・システムのエラー
パーミッション・エラー
プロトコル・エラー
キューに関するエラー
リリース間の互換性に関するエラー
リソース・マネージャ・エラー
タイムアウト・エラー
トランザクション・エラー
型付きバッファのエラー
アプリケーション・エラー
エラー処理
リスト11-1 エラー処理
リスト11-2 tpstrerrordetail()によるエラー処理
トランザクションについて
通信規則
トランザクション・エラー
致命的ではないトランザクション・エラー
致命的なトランザクション・エラー
ヒューリスティックな判断に関するエラー
トランザクション・タイムアウト
tpcommit()関数への影響
TPNOTRANフラグへの影響
tpreturn( )およびtpforward( )関数
tpterm()関数
リソース・マネージャ
トランザクションのサンプル・シナリオ
呼出し側と同じトランザクションでのサービス呼出し
AUTOTRANが設定された別のトランザクションでのサービス呼出し
図11-1 AUTOTRANが設定されたtpforward()とtpreturn()のトランザクションでの役割
新しい明示的なトランザクションを開始するサービスの呼出し
Oracle Tuxedoシステムで提供されるサブルーチン
中央イベント・ログ
ログの名前
ログ・エントリの形式
イベント・ログへの書込み
アプリケーション・プロセスのデバッグ
UNIXプラットフォーム上でのアプリケーション・プロセスのデバッグ
Windows 2003プラットフォーム上でのアプリケーション・プロセスのデバッグ
全般的なサンプル・コード
リスト11-3 ACCTサーバー
リスト11-3 ACCTサーバー
001 #include <stdio.h> /* UNIX */002 #include <string.h> /* UNIX */003 #include <fml.h> /* BEA Tuxedo System */004 #include <atmi.h> /* BEA Tuxedo System */005 #include <Usysflds.h> /* BEA Tuxedo System */006 #include <sqlcode.h> /* BEA Tuxedo System */007 #include <userlog.h> /* BEA Tuxedo System */008 #include "bank.h" /* BANKING #defines */009 #include "bank.flds.h" /* bankdb fields */010 #include "event.flds.h" /* event fields */011012013 EXEC SQL begin declare section;014 static long account_id; /* account id */015 static long branch_id; /* branch id */016 static float bal, tlr_bal; /* BALANCE */017 static char acct_type; /* account type*/018 static char last_name[20], first_name[20]; /* last name, first name */019 static char mid_init; /* middle initial */020 static char address[60]; /* address */021 static char phone[14]; /* telephone */022 static long last_acct; /* last account branch gave */023 EXEC SQL end declare section; 024 static FBFR *reqfb; /* fielded buffer for request message */025 static long reqlen; /* length of request buffer */026 static char amts[BALSTR]; /* string representation of float */ 027 code for OPEN_ACCT service 028 /*029 * Service to close an account030 */ 031 void032 #ifdef __STDC__033 LOSE_ACCT(TPSVCINFO *transb) 034 #else 035 CLOSE_ACCT(transb)036 TPSVCINFO *transb;037 #endif 038 {039 FBFR *transf; /* fielded buffer of decoded message */ 040 /* set pointer to TPSVCINFO data buffer */041 transf = (FBFR *)transb->data; 042 /* must have valid account number */043 if (((account_id = Fvall(transf, ACCOUNT_ID, 0)) < MINACCT) ||044 (account_id > MAXACCT)) {045 (void)Fchg(transf, STATLIN, 0, "Invalid account number", (FLDLEN)0);046 tpreturn(TPFAIL, 0, transb->data, 0L, 0);047 } 048 /* Set transaction level */049 EXEC SQL set transaction read write; 050 /* Retrieve AMOUNT to be deleted */051 EXEC SQL declare ccur cursor for052 select BALANCE from ACCOUNT where ACCOUNT_ID = :account_id;053 EXEC SQL open ccur;054 EXEC SQL fetch ccur into :bal;055 if (SQLCODE != SQL_OK) { /* nothing found */056 (void)Fchg(transf, STATLIN, 0, getstr("account",SQLCODE), (FLDLEN)0);057 EXEC SQL close ccur;058 tpreturn(TPFAIL, 0, transb->data, 0L, 0);059 } 060 /* Do final withdrawal */ 061 /* make withdraw request buffer */062 if ((reqfb = (FBFR *)tpalloc("FML",NULL,transb->len)) == (FBFR *)NULL) {063 (void)userlog("tpalloc failed in close_acct\n");064 (void)Fchg(transf, STATLIN, 0,065 "Unable to allocate request buffer", (FLDLEN)0);066 tpreturn(TPFAIL, 0, transb->data, 0L, 0);067 }068 reqlen = Fsizeof(reqfb);069 (void)Finit(reqfb,reqlen); 070 /* put ID in request buffer */071 (void)Fchg(reqfb,ACCOUNT_ID,0,(char *)&account_id, (FLDLEN)0); 072 /* put amount into request buffer */073 (void)sprintf(amts,"%.2f",bal);074 (void)Fchg(reqfb,SAMOUNT,0,amts, (FLDLEN)0); 075 /* increase the priority of this withdraw */076 if (tpsprio(PRIORITY, 0L) == -1)077 (void)userlog("Unable to increase priority of withdraw"); 078 /* tpcall to withdraw service to remove remaining balance */079 if (tpcall("WITHDRAWAL", (char *)reqfb, 0L, (char **)&reqfb,080 (long *)&reqlen,TPSIGRSTRT) == -1) {081 (void)Fchg(transf, STATLIN, 0,"Cannot make withdrawal", (FLDLEN)0);082 tpfree((char *)reqfb);083 tpreturn(TPFAIL, 0,transb->data, 0L, 0);084 } 085 /* Delete account record */ 086 EXEC SQL delete from ACCOUNT where current of ccur;087 if (SQLCODE != SQL_OK) { /* Failure to delete */088 (void)Fchg(transf, STATLIN, 0,"Cannot close account", (FLDLEN)0);089 EXEC SQL close ccur;090 tpfree((char *)reqfb);091 tpreturn(TPFAIL, 0, transb->data, 0L, 0);092 }093 EXEC SQL close ccur; 094 /* prepare buffer for successful return */095 (void)Fchg(transf, SBALANCE, 0, Fvals(reqfb,SAMOUNT,0), (FLDLEN)0);096 (void)Fchg(transf, FORMNAM, 0, "CCLOSE", (FLDLEN)0);097 (void)Fchg(transf, STATLIN, 0, " ", (FLDLEN)0);098 tpfree((char *)reqfb);099 tpreturn(TPSUCCESS, 0, transb->data, 0L, 0);100 }
Oracle® Tuxedo
12cリリース2 (12.2.2)
Oracle Tuxedo C言語を使用したOracle Tuxedo ATMIアプリケーションのプログラミング, 12cリリース2 (12.2.2)

Copyright ©1994, 2017,Oracle and/or its affiliates. All rights reserved