![]() |
![]() |
|
|
トランザクションの開始
グローバル・トランザクションを開始するには、次の文法を使用して tpbegin(3c) 関数を呼び出します。
int
tpbegin(unsigned long timeout, long flags)
次の表は、tpbegin() 関数の引数を示しています。
tpbegin() は、どのプロセスからも呼び出すことができます。ただし、既にトランザクション・モードになっているプロセス、または未処理の応答を待っているプロセスからは呼び出すことができません。トランザクション・モードで tpbegin() が呼び出されると、プロトコル・エラーになって呼び出しが失敗し、tperrno(5) に TPEPROTO が設定されます。プロセスがトランザクション・モードの場合でも、この失敗はトランザクションには影響しません。
次のコード例は、グローバル・トランザクションの定義方法を簡単に示しています。
グローバル・トランザクションの定義 - 簡単な例
. . .
if (tpbegin(timeout,flags) == -1)
error routine
program statements
. . .
if (tpcommit(flags) == -1)
error routine
次のコード例は、トランザクションの定義方法をより詳細に示しています。このコードは、BEA Tuxedo システムで提供される銀行業務のサンプル・アプリケーション bankapp の audit.c クライアント・プログラムから引用したものです。
グローバル・トランザクションの定義 - 詳細な例
#include <stdio.h> /* UNIX */
#include <string.h> /* UNIX */
#include <atmi.h> /* BEA Tuxedo システム */
#include <Uunix.h> /* BEA Tuxedo システム */
#include <userlog.h> /* BEA Tuxedo システム */
#include "bank.h" /* 銀行業務アプリケーションのマクロ定義 */
#include "aud.h" /* 銀行業務アプリケーションの VIEW 定義 */
#define INVI 0 /* 残高照会 */
#define ACCT 1 /* 残高照会 */
#define TELL 2 /* 窓口の残高照会 */
static int sum_bal _((char *, char *));
static long sitelist[NSITE] = SITEREP; /* 監査用マシンのリスト */
static char pgmname[STATLEN]; /* プログラム名 = argv[0] */
static char result_str[STATLEN]; /* 照会の結果を入れる配列 */
main(argc, argv)
int argc;
char *argv[];
{
int aud_type=INVI; /* 監査の種類―指定されていない場合は無効 */
int clarg; /* optind からのコマンド行引数のインデックス */
int c; /* オプション文字 */
int cflgs=0; /* コミットのフラグ。現在使用されていません。 */
int aflgs=0; /* アボートのフラグ。現在使用されていません。 */
int nbl=0; /* 支店リストのエントリ数 */
char svc_name[NAMELEN]; /* サービス名 */
char hdr_type[NAMELEN]; /* 出力の表題 */
int retc; /* sum_bal() の戻り値 */
struct aud *audv; /* audit バッファ構造体へのポインタ */
int audrl=0; /* audit の戻り値の長さ */
long q_branchid; /* 照会する支店番号 */
. . . /* コマンド行オプションの取得と変数の設定 */
/* アプリケーションへの参加 */
if (tpinit((TPINIT *) NULL) == -1) {
(void)userlog("%s:failed to join application\n", pgmname);
exit(1);
}
/* グローバル・トランザクションの開始 */
if (tpbegin(30, 0) == -1) {
(void)userlog("%s:failed to begin transaction\n", pgmname);
(void)tpterm();
exit(1);
}
if (nbl == 0) { /* 支店番号が指定されていないので、総勘定を計算 */
retc = sum_bal(svc_name, hdr_type); /* sum_bal ルーチンは省略 */
} else {
/* バッファを作成し、データ・ポインタを設定します。 */
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);
}
/* aud 構造体を用意します。 */
audv->b_id = q_branchid;
audv->balance = 0.0;
audv->ermsg[0] = '\0';
/* 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);
}
/* グローバル・トランザクションのコミット */
if (retc < 0) /* sum_bal の実行が失敗したので処理をアボート */
(void) tpabort(aflgs);
else {
if (tpcommit(cflgs) == -1) {
(void)userlog("%s:failed to commit transaction\n", pgmname);
(void)tpterm();
exit(1);
}
/*トランザクションのコミットが成功した場合のみ、結果を出力 */
(void)printf("%s",result_str);
}
/* アプリケーションからの分離 */
if (tpterm() == -1) {
(void)userlog("%s:failed to leave application\n", pgmname);
exit(1);
}
トランザクションがタイムアウトになった場合、tpcommit() を呼び出すとトランザクションがアボートします。その結果、tpcommit() が失敗し、tperrno(5) に TPEABORT が設定されます。
次のコード例は、トランザクションのタイムアウトを確認する方法を示しています。timeout の値が 30 秒に設定されていることに注目してください。
トランザクションのタイムアウトの確認
if (tpbegin(30, 0) == -1) {
(void)userlog("%s:failed to begin transaction\n", argv[0]);
tpterm();
exit(1);
}
. . .
communication calls
. . .
if (tperrno == TPETIME){
if (tpabort(0) == -1) {
check for errors;
}
else if (tpcommit(0) == -1){
check for errors;
}
. . .
注記 トランザクション・モードのプロセスで、flags 引数に TPNOTRAN を設定して通信呼び出しを行うと、呼び出されたサービスは現在のトランザクションに参加できません。サービス要求の成功や失敗は、トランザクションの結果に影響しません。トランザクションは、サービスから応答が返されるのを待つ間にタイムアウトになる場合もあります。これは、そのサービスがトランザションに参加しているかどうかには関係ありません。TPNOTRAN フラグの影響については、「エラーの管理」を参照してください。
![]() |
![]() |
![]() |
|
Copyright © 2001 BEA Systems, Inc. All rights reserved.
|