BEA Logo BEA Tuxedo Release 8.0

  BEA ホーム  |  イベント  |  ソリューション  |  パートナ  |  製品  |  サービス  |  ダウンロード  |  ディベロッパ・センタ  |  WebSUPPORT

 

   Tuxedo ホーム   |   C 言語を使用した BEA Tuxedo アプリケーションのプログラミング   |   先頭へ   |   前へ   |   次へ   |   目次

 


全般的なコード例

トランザクションの整合性、メッセージの通信、およびリソースへのアクセスは、オンライン・トランザクション処理 (OLTP) アプリケーションの主要な要件です。

ここでは、リソース・マネージャにアクセスする SQL 文と共に動作する通信ルーチン、バッファ管理、ATMI トランザクションを示すコード例を示します。ここで示す例は、BEA Tuxedo 銀行業務アプリケーション (bankapp) のACCT サーバから抜粋した CLOSE_ACCT サービスです。

この例は、最初の SQL 文でデータベースにアクセスする前に、set transaction 文 (49 行目) を使用して、トランザクションの整合性レベルとアクセス・モードを設定する方法を示しています。読み取り/書き込みの権限が指定されている場合、整合性レベルはデフォルトで高い整合性に設定されます。ACCOUNT_ID の値に基づいて口座を解約するために、SQL クエリで引き出し額を決定します (50 〜 58 行目)。

tpalloc() は、WITHDRAWAL サービスへの要求メッセージ用のバッファを割り当て、ACCOUNT_ID と引き出し額がバッファに格納されます (62 〜 74 行目)。次に、tpcall() を介して WITHDRAWAL サービスに要求が送信されます (79 行目)。その後、SQL の delete 文で、該当する口座を削除してデータベースを更新します (86 行目)。

すべての処理が成功すると、サービス内で割り当てられたバッファが解放され (98 行目)、サービスに送信された TPSVCINFO データ・バッファが更新されて、トランザクションが正常に終了したことが示されます (99 行目)。サービスがイニシエータであった場合、ここでトランザクションが自動的にコミットされます。tpreturn() は、口座の解約を要求したクライアント・プロセスに、TPSUCCESS と更新後のバッファを返します。最後に、要求されたサービスが正常に終了したことが、フォームのステータス行に示されます。

各関数呼び出しの後、成功したか失敗したかが確認されます。エラーが発生した場合、サービスで割り当てられたバッファが解放され、サービスで開始されたトランザクションがアボートされ、TPSVCINFO バッファが更新されてエラーの原因が示されます (80 〜 83 行目)。最後に、tpreturn()TPFAIL を返し、更新されたバッファ内のメッセージがフォームのステータス行に表示されます。

注記 サービス・ルーチンでグローバル・トランザクションの整合性レベルを指定する場合、同じトランザクションに参加するすべてのサービス・ルーチンで、同じようにレベルを定義する必要があります。

ACCT サーバ

001   #include <stdio.h>              /* UNIX */
002 #include <string.h> /* UNIX */
003 #include <fml.h> /* BEA Tuxedo システム */
004 #include <atmi.h> /* BEA Tuxedo システム*/
005 #include <Usysflds.h> /* BEA Tuxedo システム */
006 #include <sqlcode.h> /* BEA Tuxedo システム */
007 #include <userlog.h> /* BEA Tuxedo システム */
008 #include "bank.h" /* 銀行業務アプリケーションのマクロ定義 */
009 #include "bank.flds.h" /* bankdb フィールド*/
010 #include "event.flds.h" /* イベント・フィールド*/
011
012
013 EXEC SQL begin declare section;
014 static long account_id; /* 口座番号 */
015 static long branch_id; /* 支店番号 */
016 static float bal, tlr_bal; /* 収支 */
017 static char acct_type; /* 口座の種類 */
018 static char last_name[20], first_name[20]; /* 姓、名 */
019 static char mid_init; /* 中間名の頭文字 */
020 static char address[60]; /* 住所 */
021 static char phone[14]; /* 電話番号 */
022 static long last_acct; /* 支店で最後に開いた口座 */
023 EXEC SQL end declare section;

024 static FBFR *reqfb; /* 要求メッセージ用のフィールド化バッファ */
025 static long reqlen; /* 要求バッファの長さ */
026 static char amts[BALSTR]; /* 浮動小数点の文字列表現 */

027 code for OPEN_ACCT service

028 /*
029 * 口座を解約するためのサービス
030 */

031 void
032 #ifdef __STDC__
033 LOSE_ACCT(TPSVCINFO *transb)

034 #else

035 CLOSE_ACCT(transb)
036 TPSVCINFO *transb;
037 #endif

038 {
039 FBFR *transf; /* 複合化されたメッセージのフィールド化されたバッファ */

040 /* TPSVCINFO データ・バッファへのポインタを設定 */
041 transf = (FBFR *)transb->data;

042 /* 口座番号が妥当かどうかを確認します。 */
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 /* トランザクション・レベルを設定します。 */
049 EXEC SQL set transaction read write;

050 /* 削除する金額を取得します。 */
051 EXEC SQL declare ccur cursor for
052 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) { /* 何も見つからなかった場合 */
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 /* 最終的な引き出しを実行します。 */

061 /* 引き出し要求バッファを設定します。 */
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 /* 要求バッファに番号を格納します。 */
071 (void)Fchg(reqfb,ACCOUNT_ID,0,(char *)&account_id, (FLDLEN)0);

072 /* 要求バッファに金額を格納します。 */
073 (void)sprintf(amts,"%.2f",bal);
074 (void)Fchg(reqfb,SAMOUNT,0,amts, (FLDLEN)0);

075 /* この引き出しの優先順位を上げます。 */
076 if (tpsprio(PRIORITY, 0L) == -1)
077 (void)userlog("Unable to increase priority of withdraw");

078 /* withdraw サービスで残額を削除するために tpcall を呼び出します。 */
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 /* 口座レコードの削除 */

086 EXEC SQL delete from ACCOUNT where current of ccur;
087 if (SQLCODE != SQL_OK) { /* 削除に失敗した場合 */
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 /* 処理が成功した場合の応答バッファを準備します。 */
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 }

 

先頭へ戻る 前のトピックへ