WebSphere Message Broker バージョン 8.0.0.5 オペレーティング・システム: AIX、HP-Itanium、Linux、Solaris、Windows、z/OS

製品の最新バージョンについては、IBM Integration Bus バージョン 9.0 をご覧ください。

エラー処理のための ESQL のコーディング

メッセージ・フロー内のメッセージを処理するとき、多くの異なる原因でエラーが発生することがあり、メッセージ・フロー設計者はそれらのエラーを処理する方法を決める必要があります。

概要

メッセージ・フロー内のメッセージを処理する際のエラーの原因として、次のものが考えられます。
  • 外部的な原因。例えば、着信メッセージが構文的に無効である、フローによって使用されるデータベースがシャットダウンされている、またはブローカーが実行されているマシンへの電源機構で障害が発生している、などです。
  • 内部的な原因。例えば、制約チェックのため行をデータベース表に挿入しようとする試みが失敗する、またはデータベースから読み取られる文字ストリングに英字が含まれるため数値に変換できない、などです。

    内部エラーは、データベースに無効なデータを保管しているプログラム、またはフローのロジックの不備によって生じる可能性があります。

メッセージ・フローの設計者は、エラーの処理方法を決める必要があります。

デフォルトのエラー処理の使用

ESQL エラーの処理に関する最も単純な方針は、何もしないでブローカーのデフォルトの動作を使用することです。 デフォルトでは、失敗したメッセージの処理を切り上げて、次のメッセージに進みます。 入出力ノードは、処理を切り上げたときの動作を正確に制御するオプションを提供します。

入出力ノードがトランザクションのモードに設定される場合、ブローカーはメッセージが処理される前に状態を復元します。
  1. 入力キューから取られたと思われる入力メッセージは書き戻される。
  2. フローが出力キューに書き込んだと思われる出力メッセージはすべて廃棄される。
入出力ノードがトランザクションのモードに設定されていない場合は、次のようになります。
  1. 入力キューから取られた入力メッセージは書き戻されない。
  2. フローが出力キューに書き込んだ出力メッセージはすべて出力キューに留まる。

これらの方針にはそれぞれに利点があります。 トランザクションのモデルがデータの整合性を保持する一方、非トランザクションのモデルではメッセージ処理の継続性が最大になります。 トランザクションのモデルでは、失敗する入力メッセージは入力キューに書き戻され、ブローカーは処理を再試行します。 このシナリオの結果として、ほとんどの場合、メッセージは再試行の限界に達するまで失敗し続けます。その限界に達すると、メッセージはデッド・レター・キューに置かれます。 メッセージ処理失敗の理由は、システム・イベント・ログ (Windows) または SYSLOG (UNIX) に記録されます。 したがって、 失敗メッセージは後続の有効なメッセージの処理を保留し、ブローカーによって未処理のままとされます。

ほとんどのデータベースはトランザクションとして動作し、メッセージの処理が成功した場合にはデータベース表に対する変更がすべてコミットされ、失敗した場合にはロールバックされるようにします。こうしてデータの整合性を維持します。 このような状態の例外としては、ブローカー自体またはデータベースが失敗するような場合があります (例えば、それらを実行しているコンピューターへの電源が中断された場合)。 このような場合、特定のデータベースの変更はコミットして、他のデータベースの変更はコミットしない可能性があります。あるいは、データベースの変更はコミットし、入出力メッセージはコミットしない可能性もあります。 このような可能性が懸念される場合は、 フローを調整して、関係するデータベースを構成する必要があります。

カスタマイズされたエラー処理の使用

次のリストには、カスタマイズされたエラー・ハンドラーを作成するためのいくつかの一般的なヒントが含まれています。
  • デフォルトのエラー処理よりも優れたものが必要な場合には、まずハンドラーを使用します。 DECLARE HANDLER ステートメントを参照。 考えられるすべての例外 (あるいは予測可能なすべての例外) を代行受信するためのハンドラーを 1 つのノードにつき 1 つ作成します。
  • エラーを代行受信したら、エラー・ハンドラーはその処理に適したロジックなら何でも使用できます。 あるいは、THROW ステートメントまたはノードを使って例外を作成することもできます。この例外はフロー・ロジックの高位で処理されるか、または入力ノードに達する場合もあり、トランザクションのロールバックを引き起こします。例外のスローを参照してください。
  • ハンドラーによってキャッチされない例外をノードが生成する場合、フローは Failure ターミナルに方向転換されるか (接続されている場合)、またはデフォルトのエラー処理によって処理されます (Failure ターミナルが接続されていない場合)。

    未処理エラーをキャッチするために Failure ターミナルを使用してください。 単純なロジック・フローを Failure ターミナルに接続してください。 このロジック・フローは、ログ・レコードをデータベース (おそらくメッセージのビット・ストリームを含む) あるいはレコードをイベント・ログに書き込むデータベース・ノードまたは Compute ノードで構成できます。 さらに、特別なキューにメッセージを書き込む出力ノードを含めることもできます。

    完全な例外ツリーが、Failure ターミナルに接続されているどのノードにも渡されます。例外リスト・ツリーの構造を参照してください。

  • エラー・ハンドラーは、各エラーを適切な場所 (システム・イベント・ログなど) に記録する責任があります。

メッセージ・フロー内でのエラーを処理するために使用できるオプションに関する詳細は、メッセージ・フローのエラー処理を参照してください。 実行できる事柄の例については、例外のスローおよびデータベース状態のキャプチャーを参照してください。

エラーを検出するためのコードの作成

以下のセクションでは、ブローカーがエラーを検出することを前提としています。 しかし、フローのロジックがエラーを検出するということもありえます。 例えば、 フロー・ロジックをコーディングする際には以下のエレメントを使用できます。
  • 特に、起きるべきでない状況を検出するために挿入される IF ステートメント
  • 不可能なコードを介した経路をトラップする CASE 式またはステートメントの ELSE 節
フロー・ロジックが検出するエラーの例として、 メッセージのタイプを示す可能な整数値の範囲を持つフィールドを考えてみましょう。 フィールドの値が既知のタイプのどのメッセージにも対応していないところにメッセージが到着した場合に発生するイベントを、成り行きに任せるのは望ましくないでしょう。 1 つの可能性として、メッセージの追加のタイプをサポートするようシステムがアップグレードされたものの、システムの一部がアップグレードされていない場合に、このような状態が起こり得ます。

独自のロジックを使用して無効な入力メッセージを処理する

構文的に無効な入力メッセージ (および誤ったメッセージ形式情報のために無効であるように見える入力メッセージ) を扱うのは困難です。 ブローカーはそのメッセージの内容を認識できないからです。 一般にそのようなメッセージを扱う最も良い方法は、構文解析が完全に行われ、メッセージを妥当性検査するように入力ノードを構成することです。 ただし、この構成は事前定義メッセージ (つまり、MRM または IDoc) のみに適用されます。

この方法で入力ノードを構成してある場合、入力メッセージを正常に構文解析できない場合は以下の結果が保障されます。
  • 入力メッセージがノードの通常の output ターミナルから現れることはない (Failure ターミナルに送られる)。
  • 入力メッセージがメッセージ・フローの主要部分に入ることはない。
  • 入力メッセージがデータベース更新の原因となることはない。
  • メッセージが出力キューに書き込まれることはない。

失敗メッセージを扱うには、単純なロジック・フローを Failure ターミナルに接続してください。 この方針の唯一の欠点は、 通常フローが一部のメッセージのフィールドへのアクセスを必要としない場合に、メッセージの完全構文解析の強制によってパフォーマンスに影響が及ぶことです。

独自のロジックを使用してデータベース・エラーを処理する

データベース・エラーは次の 3 つのカテゴリーに分類されます。
  • データベースが作動しない (例えばオフラインになっている)。
  • データベースは作動するが要求を拒否する (例えばロックの競合が発生する)。
  • データベースは作動するが、ユーザーの要求を実行できない (例えば、存在しない表からの読み取りなど)。

デフォルトのエラー処理よりも優れたものが必要な場合には、まずハンドラーを使用して (DECLARE HANDLER ステートメントを参照) 例外を代行受信します。 ハンドラーは、データベースによって戻される SQL 状態から、失敗の性質を判別できます。

データベースが作動していない
データベースがまったく作動せず、そのデータベースがメッセージの処理に不可欠の場合、ユーザーが行えることは一般に多くありません。 ハンドラーは原因を判別した後、以下のアクションのうち 1 つ以上を完了する可能性があります。
  • RESIGNAL ステートメントを使用して元のエラーを再スローし、デフォルトのエラー・ハンドラーが引き継ぐようにする。
  • 別のデータベースを使用する。
  • 特別な出力キューにメッセージを書き込む。

    この手法と類似した方法を使用する場合には注意してください。ハンドラーは例外を吸収するため、他方のデータベースに対する変更またはキューに対する書き込みはすべてコミットされます。

データベースが要求を拒否する
ロックの競合が発生するときの状況は、「データベースが作動しない」場合に似ています。これはデータベースが、失敗する要求だけでなく、現行メッセージに関して行ったデータベース変更すべて をバックアウトするからです。 ですから、それが唯一の更新であったことが確実でない場合は、おそらくエラーのロギングまたはメッセージの特別なキューへの引き渡しを除き、一般にデフォルトのエラー処理が最善の方針です。
不可能な要求
データベースが作業中に不可能な要求が生じ、その要求されたアクションを完了することができません。 このタイプのエラーには広範な種類の問題が含まれます。
前述の例に説明されているように、フローが予期した名前の表をデータベースが持っていない場合、おそらくエラーのロギングまたはメッセージの特別なキューへの引き渡しを除き、一般にデフォルトのエラー処理が最善の方針です。

しかし、他の多くのエラーは正常に処理できます。 例えば、 行を挿入しようとする場合、その種の行がすでに存在するため、新規行は重複することになり、その試行は失敗するかもしれません。 またはその種の行が存在しない (つまり更新アクションによって行がまったく更新されなかった) ために行の更新試行が失敗することも考えられます。 このような場合、適切と思われるロジックなら何でもハンドラーは取り込むことができます。 欠落行を挿入するかもしれませんし、既存の行を使用するかもしれません (おそらくその値が適切なものであることを確認するでしょう)。

ゼロ行の更新をエラーとして報告するには、ノードの「警告をエラーとして扱う」プロパティーを「true」に設定する必要があります。これは、デフォルト設定ではありません。

独自のロジックを使用して出力ノードのエラーを処理する

MQOutput ノードで発生するエラーは、SQL 状態のエラーの性質を報告し、SQL native error 変数に追加情報を提供します。 したがって、デフォルトのエラー処理よりも優れたものが必要な場合には、まずハンドラーを使用して (DECLARE HANDLER ステートメントを参照) 例外を代行受信します。 そうしたハンドラーは通常、単一の PROPAGATE ステートメントのみを囲みます。

独自のロジックを使用してその他のエラーを処理する

上記で扱われているエラーの他にもさまざまなエラーが発生し得ます。 例えば、 算術計算のオーバーフロー、データの不適切によるキャストの失敗、タイプの制約によるメッセージ・フィールドへのアクセスの失敗などです。 ブローカーはこれらのタイプのエラーを扱うための 2 つのプログラミング・ストラテジーを提供しています。
  • 処理されるかまたはトランザクションをロールバックするために残される例外がエラーによって発生する。
  • 後にテストされる特殊値として失敗が記録される。

タイプの制約がない場合に、存在しないメッセージ・フィールドにアクセスしようとすると値がヌルになります。 ヌル値は式を介して伝搬し、結果をヌルにします。 したがって、式 (複雑な式) がヌル値を戻さなければ、式がその結果を計算する必要があった値すべてがヌルでなかったことを知ります。

キャスト式にはデフォルトの文節がある場合があります。 デフォルトの文節がある場合、キャストはそれとは分かりにくい形で失敗します。 例外をスローする代わりに、ただデフォルト値を戻します。 デフォルト値には、無害な数値 (例えば整数の場合のゼロ)、またはコンテキストの中で明らかに無効な値 (例えば顧客番号の場合の -1) を使用できますが、 ヌルがとりわけ適しているかもしれません。なぜならヌルは、他のすべてのものと異なり、エラー条件がマスクされる可能性がまったくなく式を介して伝搬する値だからです。

他のノードのエラー処理

他のノードで発生する例外 (つまり、PROPAGATE ステートメントのダウンストリーム) は、ハンドラーによって通常の方法でキャッチされます。 ただし、このようなエラーをふさわしく処理しようとすると、問題が生じます。つまり、元のエラーに別のノードが関係していたため、別のノード (例外の発信元であるとは限らない) がエラーの処理に関係している可能性が非常に高いのです。

このような状態で役立つよう、Database および Compute ノードには、Out1、Out2、Out3、および Out4 という 4 つのターミナルが用意されています。 さらに、PROPAGATE ステートメントの構文には、ターゲット式、メッセージ・ソースおよび制御の文節が組み込まれ、これらのターミナルをより良く制御できるようになりました。

特記事項 | 商標 | ダウンロード | ライブラリー | サポート | フィードバック

Copyright IBM Corporation 1999, 2014Copyright IBM Corporation 1999, 2014.

        
        最終更新:
        
        最終更新: 2015-02-28 17:45:35


概念トピック概念トピック | バージョン 8.0.0.5 | ac17140_