Error Handler サンプルについて

Error Handler サンプルは、トランザクションの処理が関係する業務において、エラーを処理するためのルーチンを開発する場合のシナリオに基づいています。このサンプルは、WebSphere Message Broker に含まれるいくつかの機能の使い方を示すものです。

銀行などにおける業務の場合、トランザクションの処理が必ず 1 度限りであり、すべてのエラーの記録が残るようにします。Error Handler サンプルでは、メッセージ・フローを使用してスタッフ番号に関するメッセージを書き込みます。そのメッセージ・フローでは、この情報でデータベースが更新されます。無効なスタッフ番号でメッセージに書き込むと、エラー処理ルーチンが機能する方法を観察できます。

Error Handler サンプルでは、以下のタスクを示します。

メッセージ

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 サンプルのメッセージ・フローのノードについて調べてください。

有効スタッフ・メッセージがたどる経路

有効スタッフ・メッセージを入力キューに入れる場合、メッセージは以下に説明されているノードを経由します。いずれかのキューが使用不可になっている場合には、メッセージはこのパスを通ることはできません。

メイン・メッセージ・フローで、次のようにします。

  1. STAFF_IN。このノードは、入力メッセージを入力キューから取得します。
  2. Error_Handler。このノードは、エラー処理サブフローを表します。メッセージはメイン・メッセージ・フローを離れ、サブフローに入ります。

サブフローで、次のようにします。

  1. Start Subflow。メッセージは、フロー内の次のノードに渡されます。
  2. Check Backout count。このノードは、バックアウト・カウントがゼロかどうかチェックします。入力メッセージがこのノードを通過するのは初めてであるため、カウントはその時点でゼロで、メッセージは次のノードに渡されます。カウントが 1 以上の場合、メッセージは廃棄されます。
  3. TryCatch。スタッフ番号は有効であるため、メッセージは Back To Main Flow ノードに渡されます。メッセージのスタッフ番号が無効で、そのことが分かった段階にまでメッセージの処理が進んでいる場合には、メッセージは Back To Main Flow ノードではなく Update Error Database ノードに渡されます。
  4. Back To Main Flow。ここで、メッセージはサブフローを離れ、メイン・メッセージ・フローに戻ります。

メイン・メッセージ・フローで、次のようにします。

  1. Check Valid Staff Number。スタッフ番号は有効であるため、メッセージは Update Staff Database ノードに渡されます。
  2. Update Staff Database。STAFFDB データベースは、メッセージ内のスタッフの詳細情報で更新されます。
  3. STAFF_OUT。このノードは、メッセージを STAFF_OUT キューに入れます。

無効スタッフ・メッセージがたどる経路

無効スタッフ・メッセージを入力キューに入れる場合、メッセージは以下に説明されているノードを経由します。いずれかのキューが使用不可になっている場合には、メッセージはこのパスを通ることはできません。各ノードの働きの詳細については、メイン・トピックの図中のノードをクリックしてください。

メイン・メッセージ・フローで、次のようにします。

  1. STAFF_IN。このノードは、入力メッセージを入力キューから取得します。
  2. Error_Handler。このノードは、エラー処理サブフローを表します。メッセージはメイン・メッセージ・フローを離れ、サブフローに入ります。

サブフローで、次のようにします。

  1. Start Subflow。メッセージは、フロー内の次のノードに渡されます。
  2. Check Backout Count。このノードは、バックアウト・カウントがゼロかどうかチェックします。入力メッセージがこのノードを通過するのは初めてであるため、カウントはその時点でゼロで、メッセージは次のノードに渡されます。以下のステップ 13 と比較してください。
  3. TryCatch。メッセージのスタッフ番号は無効ですが、このことはまだ分かっていません。その結果、入力メッセージは Update Error Database ノードではなく、Back To Main Flow ノードに渡されます。
  4. Back To Main Flow。ここで、メッセージはサブフローを離れ、メイン・メッセージ・フローに戻ります。

メイン・メッセージ・フローで、次のようにします。

  1. Check Valid Staff Number。スタッフ番号は無効であるため、メッセージは Update Staff Database ノードではなく、Throw Exception ノードに渡されます。
  2. Throw Exception。このノードは、メッセージの処理を停止し、メッセージの内容にエラー番号「3001」と「Invalid staff number」というテキストを記録します。これでメッセージは、「ロールバック」されます。つまり、メッセージは制御のポイントまで伝搬されます。この場合は、サブフローの TryCatch ノードです。

サブフローで、次のようにします。

  1. TryCatch。このノードは、メッセージの処理で例外が生じたことを認識し、メッセージを Update Error Database ノードに渡します。
  2. Update Error Database。ERRORDB データベースは、Throw exception ノードで設定されたように、エラーの詳細情報で更新されます (ステップ 8)。
  3. Throw To Complete Rollback。このノードはメッセージの処理を停止し、メッセージの内容に番号「3002」と「From Error_Handler message flow. See ERRORDB for details」というテキストを記録します。これで、メッセージは制御のポイントまで伝搬されます。この場合、メイン・メッセージ・フローの STAFF_IN ノードです。
    これは、捕捉処理の最終段階です。これには、トランザクション制御下での元の try パス上のデータベース更新 (つまりメイン・フローでの STAFFDB 更新) を含む、トランザクション全体をロールバックするという効果があります。しかし、ERRORDB 更新 (トランザクション制御下にない) は、依然としてコミットされます。

メイン・メッセージ・フローで、次のようにします。

  1. STAFF_IN。メッセージの処理で例外が生じたため、メッセージはメッセージ・フローを再び経由するのではなく、STAFF_FAIL ノードに渡されます。
  2. 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 サンプルでは次の構造を使用します。

このサンプルには、1 つだけでなく 2 つのデータベースが存在します。WebSphere MQ では同一のデータベース接続を同一のメッセージ・フローで、整合トランザクションと不整合トランザクションの両方に使用できないためです。Error Handler サンプルでは、メイン・メッセージ・フローでのデータベース更新はトランザクション制御下にあるため、エラーが発生すると、その更新はロールバックされ、コミットされません。サブフローでのデータベース更新はトランザクション制御下にないため、更新は常にコミットされます。結果として、Error Handler サンプルでは 2 つの別個のデータベースが必要となります。

詳しくは、WebSphere Message Broker 資料で、メッセージ・フローでのトランザクションの調整に ついて調べてください。

メインページのアイコン   サンプルのホームに戻る