Error Handler サンプルについて
Error Handler サンプルは、トランザクションの処理が関係する業務において、エラーを処理するためのルーチンを開発する場合のシナリオに基づいています。このサンプルは、WebSphere Message Broker に含まれるいくつかの機能の使い方を示すものです。
銀行などにおける業務の場合、トランザクションの処理が必ず 1 度限りであり、すべてのエラーの記録が残るようにします。Error Handler サンプルでは、メッセージ・フローを使用してスタッフ番号に関するメッセージを書き込みます。そのメッセージ・フローでは、この情報でデータベースが更新されます。無効なスタッフ番号でメッセージに書き込むと、エラー処理ルーチンが機能する方法を観察できます。
Error Handler サンプルでは、以下のタスクを示します。
- エラーに関する情報をトラップするためにエラー処理ルーチンを使用する方法、およびデータベースにその情報を格納する方法。このサンプルで使用されるエラー・ハンドラー・ルーチンは、メッセージ・フローに追加できる、未変更のサブフローです。
- メッセージ・フローを構成してトランザクションを制御する方法。特にこのサンプルでは、データ保全性全体を確保するためのグローバル調整トランザクションの使用法が示されます。z/OS の場合、これが操作のデフォルト・モードです。分散プラットフォームの場合には、グローバル調整には特定の構成ステップが必要で、これは XA プロトコルを使用してインプリメントされます。このサンプルでは、サンプルのメイン・メッセージ・フローがスタッフ番号に関する情報で DB2 データベースを更新します。エラー処理サブフローは、スタッフ番号が処理された際に生じたエラーに関する情報で別の DB2 データベースを更新します。メイン・フローでのデータベース更新はトランザクションの制御下で実行されるため、エラーが発生して、メッセージがエラー処理サブフローで処理されると、スタッフ番号に関するデータベース更新はロールバックされ、コミットされません。エラー・ハンドラー・サブフローでのデータベース更新はトランザクションの制御下では実行されないため、エラーに関する情報がロールバックされないようにします。これは、エラーの記録を提供するためにその情報をコミットする必要があるためです。
メッセージ
Error Handler サンプルを実行するための 2 つの入力メッセージが提供されています。
1 つは有効なスタッフのシリアル番号を含むメッセージで、もう 1 つは無効なスタッフのシリアル番号を含むメッセージです。
有効スタッフ・メッセージは、以下のように XML で表現されます。
<Staff>
<StaffNumber>1</StaffNumber>
<NameInfo>
<LastName>Smith</LastName>
<FirstName>Jack</FirstName>
</NameInfo>
</Staff>
無効スタッフ・メッセージは、以下のように XML で表現されます。
<Staff>
<StaffNumber>99</StaffNumber>
<NameInfo>
<LastName>Doe</LastName>
<FirstName>Jane</FirstName>
</NameInfo>
</Staff>
メッセージ・フロー
次の図は、メイン・メッセージ・フローを示しています。

次の図は、エラー処理サブフローを示しています。
下の表では、Error Handler サンプルで使用されるノードのタイプをリストしています。
Subflow ノードは、技術的にはノードではなく、ノード・パレットで使用することはできません。
つまり、Subflow ノードは単に、サブフロー Error_Handler.msgflow がメイン・メッセージ・フロー内で呼び出される場所を
表しているにすぎません。
ノード・タイプ |
ノード名 |
MQInput |
STAFF_IN |
MQOutput |
STAFF_FAIL、STAFF_OUT |
Database |
Update Staff Database、Update Error Database |
Filter |
Check Valid Staff Number、Check Backout Count |
Throw |
Throw、Throw to Complete Rollback |
TryCatch |
TryCatch |
Subflow |
Error_Handler |
詳しくは、WebSphere Message Broker 資料で、Error Handler サンプルのメッセージ・フローのノードについて調べてください。
有効スタッフ・メッセージがたどる経路
有効スタッフ・メッセージを入力キューに入れる場合、メッセージは以下に説明されているノードを経由します。いずれかのキューが使用不可になっている場合には、メッセージはこのパスを通ることはできません。
メイン・メッセージ・フローで、次のようにします。
- STAFF_IN。このノードは、入力メッセージを入力キューから取得します。
- Error_Handler。このノードは、エラー処理サブフローを表します。メッセージはメイン・メッセージ・フローを離れ、サブフローに入ります。
サブフローで、次のようにします。
- Start Subflow。メッセージは、フロー内の次のノードに渡されます。
- Check Backout count。このノードは、バックアウト・カウントがゼロかどうかチェックします。入力メッセージがこのノードを通過するのは初めてであるため、カウントはその時点でゼロで、メッセージは次のノードに渡されます。カウントが 1 以上の場合、メッセージは廃棄されます。
- TryCatch。スタッフ番号は有効であるため、メッセージは Back To Main Flow ノードに渡されます。メッセージのスタッフ番号が無効で、そのことが分かった段階にまでメッセージの処理が進んでいる場合には、メッセージは Back To Main Flow ノードではなく Update Error Database ノードに渡されます。
- Back To Main Flow。ここで、メッセージはサブフローを離れ、メイン・メッセージ・フローに戻ります。
メイン・メッセージ・フローで、次のようにします。
- Check Valid Staff Number。スタッフ番号は有効であるため、メッセージは Update Staff Database ノードに渡されます。
- Update Staff Database。STAFFDB データベースは、メッセージ内のスタッフの詳細情報で更新されます。
- STAFF_OUT。このノードは、メッセージを STAFF_OUT キューに入れます。
無効スタッフ・メッセージがたどる経路
無効スタッフ・メッセージを入力キューに入れる場合、メッセージは以下に説明されているノードを経由します。いずれかのキューが使用不可になっている場合には、メッセージはこのパスを通ることはできません。各ノードの働きの詳細については、メイン・トピックの図中のノードをクリックしてください。
メイン・メッセージ・フローで、次のようにします。
- STAFF_IN。このノードは、入力メッセージを入力キューから取得します。
- Error_Handler。このノードは、エラー処理サブフローを表します。メッセージはメイン・メッセージ・フローを離れ、サブフローに入ります。
サブフローで、次のようにします。
- Start Subflow。メッセージは、フロー内の次のノードに渡されます。
- Check Backout Count。このノードは、バックアウト・カウントがゼロかどうかチェックします。入力メッセージがこのノードを通過するのは初めてであるため、カウントはその時点でゼロで、メッセージは次のノードに渡されます。以下のステップ 13 と比較してください。
- TryCatch。メッセージのスタッフ番号は無効ですが、このことはまだ分かっていません。その結果、入力メッセージは Update Error Database ノードではなく、Back To Main Flow ノードに渡されます。
- Back To Main Flow。ここで、メッセージはサブフローを離れ、メイン・メッセージ・フローに戻ります。
メイン・メッセージ・フローで、次のようにします。
- Check Valid Staff Number。スタッフ番号は無効であるため、メッセージは Update Staff Database ノードではなく、Throw Exception ノードに渡されます。
- Throw Exception。このノードは、メッセージの処理を停止し、メッセージの内容にエラー番号「3001」と「Invalid staff number」というテキストを記録します。これでメッセージは、「ロールバック」されます。つまり、メッセージは制御のポイントまで伝搬されます。この場合は、サブフローの TryCatch ノードです。
サブフローで、次のようにします。
- TryCatch。このノードは、メッセージの処理で例外が生じたことを認識し、メッセージを Update Error Database ノードに渡します。
- Update Error Database。ERRORDB データベースは、Throw exception ノードで設定されたように、エラーの詳細情報で更新されます (ステップ 8)。
- Throw To Complete Rollback。このノードはメッセージの処理を停止し、メッセージの内容に番号「3002」と「From Error_Handler message flow. See ERRORDB for details」というテキストを記録します。これで、メッセージは制御のポイントまで伝搬されます。この場合、メイン・メッセージ・フローの STAFF_IN ノードです。
これは、捕捉処理の最終段階です。これには、トランザクション制御下での元の try パス上のデータベース更新 (つまりメイン・フローでの STAFFDB 更新) を含む、トランザクション全体をロールバックするという効果があります。しかし、ERRORDB 更新 (トランザクション制御下にない) は、依然としてコミットされます。
メイン・メッセージ・フローで、次のようにします。
- STAFF_IN。メッセージの処理で例外が生じたため、メッセージはメッセージ・フローを再び経由するのではなく、STAFF_FAIL ノードに渡されます。
- STAFF_FAIL。このノードは、メッセージを STAFF_FAIL キューに入れます。また、STAFF_FAIL キューが使用不可の場合には、ここではメッセージは停止しません。STAFF_IN ノードに再び渡され、サブフローに送られます。その後、Check Backout Count ノードに到達します。このノードは、バックアウト・カウントがゼロかどうかチェックします。メッセージはこのノードを以前に経由しているので、バックアウト・カウントはゼロではなく、メッセージは廃棄されます。STAFF_FAIL キューが使用不可の場合に、メッセージを廃棄することにより、メッセージがフローを何度も繰り返し行ったり来たりせずに済みます。上記のステップ 4 と比較してください。
TryCatch ノードを使用する場合、またはノードを MQInput ノードの Catch ターミナルに接続する場合、ノードが適切に構成されているのであれば、Catch パスが起動している場合に Try パス上で生じたすべての処理はコミットされないと想定するかもしれません。しかし、これは正しくありません。たとえば、トランザクション制御下でデータベースを Try パス上で更新し、Catch パスが起動して通常通りに完了する場合、データベースの更新はその後もコミットされます。
このサンプルにおける要件は、メッセージを読み取り、データベースを更新し、別のキューにそのメッセージを書き込むことです。エラーが発生すると、データベース更新はロールバックされます。捕捉処理によって、エラーの詳細でエラー・データベースが更新され、元のメッセージは障害の発生したキューに書き込まれます。プログラミングでは、次のようになります。
BEGIN (Start 'outer' unit-of-work.)
MQGET (Get message from the input queue.)
TRY
BEGIN (Start 'inner' unit-of-work.)
Update database
MQPUT (Put message onto the output queue.)
IF ERROR
ROLLBACK inner unit-of-work GO TO CATCH
ELSE
COMMIT inner and outer unit-of-work as one unit-of-work
END IF
CATCH
Update error database
MQPUT (Put message onto the failure queue.)
COMMIT outer unit-of-work
しかし、XA Transaction Manager および WebSphere MQ は、同一アプリケーションでの 2 つのレベルの作業単位は
サポートしていません。
そのため、Error Handler サンプルでは次の構造を使用します。
- Try パスにおけるデータベース更新は、トランザクション制御の範囲で行われます。サンプルでは、STAFFDB 更新です。
- Catch パスにおけるデータベース更新は、トランザクション制御の範囲外で行われます。これは、ERRORDB データベースです。
- MQInput ノードの Failure ターミナルは、failure キューをポイントする MQOutput ノードに接続します。
- 捕捉処理の最後の段階は、Throw ノードを使用して、エラーを再び出すことです。
- 次に、メッセージは failure パスを MQInput ノードまでロールバックし、そこから failure キューにさらに送られます。
このサンプルには、1 つだけでなく 2 つのデータベースが存在します。WebSphere MQ では同一のデータベース接続を同一のメッセージ・フローで、整合トランザクションと不整合トランザクションの両方に使用できないためです。Error Handler サンプルでは、メイン・メッセージ・フローでのデータベース更新はトランザクション制御下にあるため、エラーが発生すると、その更新はロールバックされ、コミットされません。サブフローでのデータベース更新はトランザクション制御下にないため、更新は常にコミットされます。結果として、Error Handler サンプルでは 2 つの別個のデータベースが必要となります。
詳しくは、WebSphere Message Broker 資料で、メッセージ・フローでのトランザクションの調整に
ついて調べてください。
サンプルのホームに戻る