3.7.1 MHPのトランザクション制御

MHPは,OpenTP1のメッセージ受信によるMHPの開始から,MHPの終了まで,必ずトランザクションになります。つまり,MHPで扱う処理はすべてOpenTP1でトランザクションと見なして処理します。

MHPのサービス関数では,トランザクション制御をする関数(dc_trn_begin関数など,dc_trnで始まる同期点取得の関数)は使えません。さらに,MHPからSPPのサービスを要求する場合,サービスを要求されたSPPでは,トランザクション制御をする関数は呼び出せません。MHPからSPPのサービスを要求するときは,そのSPPの処理でトランザクション制御をする関数を呼び出していないことを確認してください。

注※
MCFの拡張機能として,MHPの処理をトランザクションとしないこともできます。これを非トランザクション属性のMHPといいます。非トランザクション属性のMHPについては,「3.8.3 非トランザクション属性のMHP」を参照してください。
<この項の構成>
(1) トランザクション属性の指定
(2) 関数を使った同期点取得
(3) MHPのロールバック処理
(4) メッセージ送受信関数がエラーリターンしてもMHPがコミットとなる場合
(5) MHPからトランザクションを開始する関数を呼び出す場合

(1) トランザクション属性の指定

MHPは,ユーザサービス定義でトランザクション属性である(atomic_update=Y)ことを指定しておきます。

(2) 関数を使った同期点取得

MHPの処理の中で,連鎖モードのコミットとして同期点を取得できます。同期点は,dc_mcf_commit関数CBLDCMCF('COMMIT ')で取得します。dc_mcf_commit関数が正常に終了すると,続くMHPの処理は新しいグローバルトランザクションとなります。

MHPから始まるグローバルトランザクションが,複数のトランザクションブランチから構成される場合(MHPからdc_rpc_call関数でSPPを呼び出しているとき)は,それぞれのトランザクションブランチの処理結果がコミットとならないかぎりコミットとなりません。コミットできない場合は,すべてのトランザクションブランチがロールバックされます。

メッセージを受信する前に,dc_mcf_commit関数で同期点を取得できません。また,dc_mcf_commit関数で同期点を取得したあとで,そのMHPでメッセージを受信できません。

dc_mcf_commit関数で同期点取得の対象となるメッセージ処理は,非同期のメッセージとアプリケーションプログラムの起動です。同期型のメッセージ送受信の処理は,同期点取得の対象にはなりません。

dc_mcf_commit関数は,MCFアプリケーション定義で非応答型(noans型)を指定したMHPからだけ呼び出せます。それ以外の型のMHPで呼び出した場合は,エラーリターンします。また,MHP以外のUAPでは,dc_mcf_commit関数は呼び出せません。

(3) MHPのロールバック処理

(a) MHPの処理が異常終了した場合

MHPが異常終了またはロールバック※1した場合は,エラーイベントが通知されます。dc_mcf_receive関数が先頭セグメントを受け取ったかどうかで,通知されるエラーイベントは異なります。

注※1
MCFアプリケーション定義(mcfaalcap -g)のrecvmsgオペランドにrを指定した場合,またはdc_mcf_rollback関数のactionにDCMCFRTRYもしくはDCMCFRRTNを指定した場合は除きます。
注※2
非常駐MHPの場合,次のような原因でMHPが起動できないときは,ERREVT2は通知されません。
  • 該当するロードモジュールが存在しない。
  • RPCインタフェース定義ファイルに記載したエントリポイントに対応したサービス関数がない。
このとき,該当するサービスグループの入力キューのスケジュールを閉塞し,受信メッセージを入力キューに残します。
(b) MHPの処理中にエラーが起こった場合

MHPのトランザクション処理がエラーとなったときは,メッセージを受信する前の状態に戻すため,ロールバックdc_mcf_rollback関数CBLDCMCF('ROLLBACK'))をMHPで呼び出してください。メッセージを受け取ったMHPがロールバックしたときに,再びOpenTP1でMHPをスケジュールし直すかどうかは,dc_mcf_rollback関数の引数の指定に従います。

メッセージ送受信形態の処理とトランザクションの関係を次の図に示します。

図3-12 メッセージ送受信形態の処理とトランザクションの関係

[図データ]

(説明)
  1. メッセージを受信した時点で,MHPから始まる処理はグローバルトランザクションになります。
  2. MHPのトランザクション処理でエラーが起こった場合は,ロールバック(部分回復)してから,MCFに制御を渡します。リターン指定(actionにDCMCFRRTNを設定)のdc_mcf_rollback関数を呼び出すと,新しいトランザクションの処理もできます。

(4) メッセージ送受信関数がエラーリターンしてもMHPがコミットとなる場合

MHPの処理で,メッセージ送受信機能の関数がエラーリターンしたあとで,リターンで処理を終了させた場合,そのトランザクション自体はコミットすることがあります。このようなMHPの処理の中でリソースマネジャ(RM)にアクセス(DAM,TAM)をしていれば,このアクセスの処理はコミットになります。アクセスの処理もロールバックとしたい場合は,エラーリターン後にdc_mcf_rollback関数を呼び出す処理を作成しておくか,abortを呼び出しておいてください。

(5) MHPからトランザクションを開始する関数を呼び出す場合

MHPでも,サービス関数の処理範囲以外(メイン関数の処理範囲)ならば,トランザクションの開始(dc_trn_begin関数)を使えます。トランザクションの開始と同期点取得は,メイン関数のdc_rpc_open関数からdc_mcf_mainloop関数の間,またはdc_mcf_mainloop関数からdc_rpc_close関数の間で呼び出せます。

MHPのメイン関数でdc_trn_begin関数を呼び出したときは,そのメイン関数で必ず非連鎖モードのコミット(dc_trn_unchained_commit関数)を呼び出して同期点を取得してください。