11.24.2 致命的なトランザクション・エラー

致命的なトランザクション・エラーが発生した場合、アプリケーションでは、イニシエータでtpabort()を呼び出してトランザクションを明示的に中断しなければなりません。そのため、トランザクションにとって致命的なエラーを認識することが大切です。次の3つの場合、トランザクションは失敗します。

  • トランザクションのイニシエータまたは参加リソースが、次のいずれかの理由により「中断のみ」にマークされました。
  • tpreturn()の引数の処理でエラーが発生しました。tperrno(5)TPESVCERRが設定されます。
    • tpreturn()rval引数がTPFAILに設定されています。tperrno(5)TPESVCFAILが設定されます。
    • 応答バッファのtypeまたはsubtypeが不明であるか、または呼出し側で使用できないので、成功したか失敗したかを判断できません。tperrno(5)TPEOTYPEが設定されます。
  • トランザクションがタイムアウトになりました。tperrno(5)TPETIMEが設定されます。
  • tpcommit()が、トランザクションの開始元ではなく参加リソースによって呼び出されています。tperrno(5)TPEPROTOが設定されます。
  • tpcommit()が、トランザクションの開始元ではなく参加リソースによって呼び出されています。tperrno(5)TPEPROTOが設定されます。

トランザクションにとって致命的なプロトコル・エラーが発生するのは、トランザクションの不正な参加リソースからtpcommit()が呼び出された場合だけです。このエラーは、アプリケーション内で開発段階に修正できます。

イニシエータまたは参加リソースで障害が発生した後、またはトランザクションがタイムアウトになった後で、tpcommit()が呼び出されると、暗黙的な中断エラーになります。その場合、コミットは失敗するので、トランザクションを中断する必要があります。

通信呼出しでTPESVCERRTPESVCFAILTPEOTYPEまたはTPETIMEが返された場合、tpabort()を呼び出してトランザクションを明示的に中断しなければなりません。トランザクションを明示的に中断する前に、未処理の呼出し記述子を待つ必要はありません。ただし、これらの記述子は、呼出しが中断された後は無効とみなされるので、トランザクション終了後にこれらの記述子へのアクセスを試みると、TPEBADDESCが返されます。

TPESVCERRTPESVCFAILおよびTPEOTYPEの場合、トランザクションがタイムアウトにならないかぎり、引き続き通信呼出しを行うことができます。これらのエラーが戻された場合、トランザクションは「中断のみ」にマークされます。これ以降の処理の結果を保持するには、flagsパラメータにTPNOTRANを設定して通信用の関数を呼び出す必要があります。このフラグを設定すると、「中断のみ」にマークされたトランザクションで実行された処理は、トランザクションが中断してもロールバックされません。

トランザクション・タイムアウトが発生しても通信を続けることはできますが、次のような通信リクエストを行うことはできません。

  • 応答を要求すること
  • ブロック
  • 呼出し側のトランザクションに対して実行すること

そのため、非同期呼出しを行うには、flagsパラメータにTPNOREPLYTPNOBLOCKまたはTPNOTRANを設定する必要があります。