BEA Logo BEA Tuxedo Release 8.0

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

 

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

 


トランザクションの開始

グローバル・トランザクションを開始するには、次の文法を使用して tpbegin(3c) 関数を呼び出します。

int
tpbegin(unsigned long timeout, long flags)

次の表は、tpbegin() 関数の引数を示しています。

tpbegin( ) 関数の引数

フィールド

説明

timeout

トランザクションがタイムアウトになるまでの時間 (秒単位)。この引数に 0 を指定すると、システムで可能な最長時間 (秒単位) に設定されます。つまり、timeout には、システムで定義された符号なし long 型の最大値が設定されます。

timeout に 0 または非現実的な大きな値を指定すると、システムによるエラー検出と報告が遅れる原因となります。timeout パラメータを使用すると、サービス要求に対する応答が妥当な時間内に確実に返されるようになります。また、ネットワーク障害などの問題が発生した場合に、コミットされる前にトランザクションを終了できます。

応答を人が待っている場合、このパラメータには小さな値 (可能な場合は 30 秒未満) を設定します。

生産システムの場合、timeout に大きな値を設定して、システムの負荷やデータベースの競合に起因する遅延に対応できるようにします。予測される平均応答時間を 2、3 倍した時間が最適です。

注記 timeout 引数に設定する値は、BEA Tuxedo のアプリケーション管理者がコンフィギュレーション・ファイルに設定した SCANUNIT パラメータの値と一致していなければなりません。SCANUNIT パラメータには、タイムアウトになったトランザクションとサービス要求でブロックされた呼び出しがないかどうかを確認、つまりスキャンする頻度を指定します。このパラメータの値は、定期的なスキャンの間隔 (走査を行う間隔) を表します。

timeout パラメータには、走査を行う間隔より大きな値を設定します。timeout パラメータに設定された値が走査を行う間隔より小さいと、トランザクションがタイムアウトになる時間と、そのタイムアウトが検出される時間にずれが生じます。SCANUNIT のデフォルト値は 10 秒です。timeout パラメータの設定値についてはアプリケーション管理者と検討し、timeout に設定した値がシステム・パラメータの値と矛盾しないようにします。

flags

現在は定義されていません。0 を設定します。

tpbegin() は、どのプロセスからも呼び出すことができます。ただし、既にトランザクション・モードになっているプロセス、または未処理の応答を待っているプロセスからは呼び出すことができません。トランザクション・モードで tpbegin() が呼び出されると、プロトコル・エラーになって呼び出しが失敗し、tperrno(5)TPEPROTO が設定されます。プロセスがトランザクション・モードの場合でも、この失敗はトランザクションには影響しません。

次のコード例は、グローバル・トランザクションの定義方法を簡単に示しています。

グローバル・トランザクションの定義 - 簡単な例

. . .
if (tpbegin(timeout,flags) == -1)
error routine
program statements
. . .
if (tpcommit(flags) == -1)
error routine

次のコード例は、トランザクションの定義方法をより詳細に示しています。このコードは、BEA Tuxedo システムで提供される銀行業務のサンプル・アプリケーション bankappaudit.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 フラグの影響については、「エラーの管理」を参照してください。

 

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