![]() |
![]() |
|
|
トランザクションの終了
グローバル・トランザクションを終了するには、tpcommit(3c) を呼び出して現在のトランザクションをコミットするか、または tpabort(3c) を呼び出して処理をアボートして、すべての操作をロールバックします。
注記 tpcall()、tpacall()、または tpconnect() を呼び出すときに flags 引数に明示的に TPNOTRAN が設定されている場合、呼び出されたサービスによって実行される操作は、トランザクションに含まれません。つまり、このようなサービスによって実行される操作は、tpabort() 関数を呼び出したときにロールバックされません。
現在のトランザクションのコミット
tpcommit(3c) 関数は、現在のトランザクションをコミットします。tpcommit() 関数から正常に制御が戻ると、現在のトランザクションの結果としてリソースに加えられた変更は永続的なものとなります。
tpcommit() 関数の呼び出しには、次の文法を使用します。
int
tpcommit(long flags)
flags 引数は現在使用されていませんが、今後のリリースとの互換性を保つためにゼロに設定してください。
トランザクションをコミットするための条件
tpcommit() を正常に実行するには、次の 2 つの条件を満たしていることが必要です。
最初の条件を満たしていない場合、呼び出しは失敗し、プロトコル・エラーを示す TPEPROTO が tperrno(5) に設定されます。2 番目または 3 番目の条件を満たしていない場合、呼び出しは失敗し、トランザクションがロールバックされたことを示す TPEABORT が tperrno() に設定されます。トランザクションに未処理の応答があるときに tpcommit() がイニシエータによって呼び出されると、トランザクションはアボートされ、トランザクションに関連する応答記述子が無効になります。パーティシパントが tpcommit() または tpabort() を呼び出しても、トランザクションには影響しません。
サービス呼び出しで TPFAIL が返されるか、またはサービス・エラーが発生すると、トランザクションは「ロールバックのみ」の状態になります。「ロールバックのみ」のトランザクションに対して tpcommit() が呼び出されると、この関数はトランザクションを取り消し、-1 を返して tperrno(5) に TPEABORT を設定します。既にタイムアウトになっているトランザクションに対して tpcommit() を呼び出した場合も同じ結果になり、tpcommit() は -1 を返して tperrno() に TPEABORT が設定されます。トランザクション・エラーの詳細については、「エラーの管理」 を参照してください。
2 フェーズ・コミット・プロトコル
tpcommit() 関数が呼び出されると、2 フェーズ・コミット・プロトコルによる通信が開始されます。このプロトコルは、その名前が示すように、次の 2 段階の処理に分かれています。
トランザクションのイニシエータが tpcommit() 関数を呼び出すと、コミット・シーケンスが開始されます。指定されたコーディネータ・グループ内の BEA Tuxedo TMS サーバ・プロセスは、コミット・プロトコルの最初のフェーズを実行する各パーティシパント・グループの TMS と通信を行います。次に、各グループの TMS は、そのグループのリソース・マネージャ (RM) に、トランザクション・マネージャ と RM 間の通信用に定義されている XA プロトコルを使用してコミットするように指示します。RM は、安定記憶域にコミット・シーケンスの前後のトランザクションの状態を書き込み、TMS に成功か失敗かを通知します。その後、TMS はトランザクション・コーディネータの TMS に応答を渡します。
トランザクション・コーディネータの TMS は、すべてのグループから成功の通知を受け取ると、トランザクションのコミット中であることをログに記録し、第 2 フェーズのコミット通知をすべてのパーティシパント・グループに送信します。その後、各グループの RM はトランザクションの更新を完了します。
トランザクション・コーディネータの TMS が、グループから第 1 フェーズのコミットの失敗の通知を受けた場合、またはグループからの応答の受信に失敗した場合、各 RM にロールバック通知を送信し、RM はすべてのトランザクション更新を以前の状態に戻します。これにより、tpcommit() は失敗し、tperrno(5) に TPEABORT が設定されます。
コミットの成功条件の選択
1 つのトランザクションに複数のグループが関係している場合、tpcommit() が正常に制御を戻すための条件として、次のいずれかを指定できます。
この 2 つの条件のいずれかを指定するには、コンフィギュレーション・ファイルの RESOURCES の CMTRET パラメータに、次のいずれかの値を設定します。
デフォルトでは、CMTRET は COMPLETE に設定されます。
後でコンフィグレーション・ファイルの設定値を変更する場合は、flags 引数に TP_CMT_LOGGED または TP_CMT_COMPLETE を設定して、tpscmt() を呼び出します。
コミット条件での妥協点
ほとんどの場合、グローバル・トランザクションのすべてのパーティシパントが第 1 フェーズの正常終了を記録した場合、第 2 フェーズも正常終了します。CMTRET に LOGGED を設定すると、tpcommit() の呼び出しから制御が多少早く戻るようになります。ただし、パーティシパントが、コミットの決定と矛盾する方法で、トランザクションの担当部分をヒューリスティックに終了する危険性があります。
このようなリスクを負うべきかどうかの選択は、アプリケーションの性質に左右されます。たとえば、財務アプリケーションなど正確さが要求されるアプリケーションでは、すべてのパーティシパントが 2 フェーズ・コミットを完了するまでは、制御を戻さないようにします。時間的な条件を重視するアプリケーションでは、正確さを犠牲にしても実行速度を上げます。
現在のトランザクションのアボート
tpabort(3c) 関数を使用すると、異常な状態を通知して、明示的にトランザクションをアボートできます。この関数は、トランザクションの応答に未処理のものがあると、その呼び出し記述子を無効にします。その場合、トランザクションで行われた変更はリソースには適用されません。tpabort() 関数の呼び出しには、次の文法を使用します。
int
tpabort(long flags)
flags 引数は現在使用されていませんが、今後のリリースとの互換性を保つためにゼロに設定してください。
例: 会話モードによるトランザクションのコミット
次の図は、グローバル・トランザクションを行う階層構造の会話型接続を示しています。
トランザクション・モードにおける接続階層構造
例: パーティシパントのエラーの確認
次のコード例では、クライアントは REPORT サービスへの同期呼び出し (18 行目) を行います。次に、通信呼び出しで返される可能性があるエラーを調べて (19 〜 34 行目) 、パーティシパントの失敗を確認します。
パーティシバントの成功/失敗の確認
001 #include <stdio.h>
002 #include "atmi.h"
003
004 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 else
042 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 }
![]() |
![]() |
![]() |
|
Copyright © 2001 BEA Systems, Inc. All rights reserved.
|