メッセージ・フロー内のメッセージを処理するとき、多くの異なる原因でエラーが発生することがあり、メッセージ・フロー設計者はそれらのエラーを処理する方法を決める必要があります。
内部エラーは、データベースに無効なデータを保管しているプログラム、またはフローのロジックの不備によって生じる可能性があります。
ESQL エラーの処理に関する最も単純な方針は、何もしないでブローカーのデフォルトの動作を使用することです。 デフォルトでは、失敗したメッセージの処理を切り上げて、次のメッセージに進みます。 入出力ノードは、処理を切り上げたときの動作を正確に制御するオプションを提供します。
これらの方針にはそれぞれに利点があります。 トランザクションのモデルがデータの整合性を保持する一方、非トランザクションのモデルではメッセージ処理の継続性が最大になります。 トランザクションのモデルでは、失敗する入力メッセージは入力キューに書き戻され、ブローカーは処理を再試行します。 このシナリオの結果として、ほとんどの場合、メッセージは再試行の限界に達するまで失敗し続けます。その限界に達すると、メッセージはデッド・レター・キューに置かれます。 メッセージ処理失敗の理由は、システム・イベント・ログ (Windows) または SYSLOG (UNIX) に記録されます。 したがって、 失敗メッセージは後続の有効なメッセージの処理を保留し、ブローカーによって未処理のままとされます。
ほとんどのデータベースはトランザクションとして動作し、メッセージの処理が成功した場合にはデータベース表に対する変更がすべてコミットされ、失敗した場合にはロールバックされるようにします。こうしてデータの整合性を維持します。 このような状態の例外としては、ブローカー自体またはデータベースが失敗するような場合があります (例えば、それらを実行しているコンピューターへの電源が中断された場合)。 このような場合、特定のデータベースの変更はコミットして、他のデータベースの変更はコミットしない可能性があります。あるいは、データベースの変更はコミットし、入出力メッセージはコミットしない可能性もあります。 このような可能性が懸念される場合は、 フローを調整して、関係するデータベースを構成する必要があります。
未処理エラーをキャッチするために Failure ターミナルを使用してください。 単純なロジック・フローを Failure ターミナルに接続してください。 このロジック・フローは、ログ・レコードをデータベース (おそらくメッセージのビット・ストリームを含む) あるいはレコードをイベント・ログに書き込むデータベース・ノードまたは Compute ノードで構成できます。 さらに、特別なキューにメッセージを書き込む出力ノードを含めることもできます。
完全な例外ツリーが、Failure ターミナルに接続されているどのノードにも渡されます。例外リスト・ツリーの構造を参照してください。
メッセージ・フロー内でのエラーを処理するために使用できるオプションに関する詳細は、メッセージ・フローのエラー処理を参照してください。 実行できる事柄の例については、例外のスローおよびデータベース状態のキャプチャーを参照してください。
構文的に無効な入力メッセージ (および誤ったメッセージ形式情報のために無効であるように見える入力メッセージ) を扱うのは困難です。 ブローカーはそのメッセージの内容を認識できないからです。 一般にそのようなメッセージを扱う最も良い方法は、構文解析が完全に行われ、メッセージを妥当性検査するように入力ノードを構成することです。 ただし、この構成は事前定義メッセージ (つまり、MRM または IDoc) のみに適用されます。
失敗メッセージを扱うには、単純なロジック・フローを Failure ターミナルに接続してください。 この方針の唯一の欠点は、 通常フローが一部のメッセージのフィールドへのアクセスを必要としない場合に、メッセージの完全構文解析の強制によってパフォーマンスに影響が及ぶことです。
デフォルトのエラー処理よりも優れたものが必要な場合には、まずハンドラーを使用して (DECLARE HANDLER ステートメントを参照) 例外を代行受信します。 ハンドラーは、データベースによって戻される SQL 状態から、失敗の性質を判別できます。
この手法と類似した方法を使用する場合には注意してください。ハンドラーは例外を吸収するため、他方のデータベースに対する変更またはキューに対する書き込みはすべてコミットされます。
しかし、他の多くのエラーは正常に処理できます。 例えば、 行を挿入しようとする場合、その種の行がすでに存在するため、新規行は重複することになり、その試行は失敗するかもしれません。 またはその種の行が存在しない (つまり更新アクションによって行がまったく更新されなかった) ために行の更新試行が失敗することも考えられます。 このような場合、適切と思われるロジックなら何でもハンドラーは取り込むことができます。 欠落行を挿入するかもしれませんし、既存の行を使用するかもしれません (おそらくその値が適切なものであることを確認するでしょう)。
ゼロ行の更新をエラーとして報告するには、ノードの「警告をエラーとして扱う」プロパティーを「true」に設定する必要があります。これは、デフォルト設定ではありません。
MQOutput ノードで発生するエラーは、SQL 状態のエラーの性質を報告し、SQL native error 変数に追加情報を提供します。 したがって、デフォルトのエラー処理よりも優れたものが必要な場合には、まずハンドラーを使用して (DECLARE HANDLER ステートメントを参照) 例外を代行受信します。 そうしたハンドラーは通常、単一の PROPAGATE ステートメントのみを囲みます。
タイプの制約がない場合に、存在しないメッセージ・フィールドにアクセスしようとすると値がヌルになります。 ヌル値は式を介して伝搬し、結果をヌルにします。 したがって、式 (複雑な式) がヌル値を戻さなければ、式がその結果を計算する必要があった値すべてがヌルでなかったことを知ります。
キャスト式にはデフォルトの文節がある場合があります。 デフォルトの文節がある場合、キャストはそれとは分かりにくい形で失敗します。 例外をスローする代わりに、ただデフォルト値を戻します。 デフォルト値には、無害な数値 (例えば整数の場合のゼロ)、またはコンテキストの中で明らかに無効な値 (例えば顧客番号の場合の -1) を使用できますが、 ヌルがとりわけ適しているかもしれません。なぜならヌルは、他のすべてのものと異なり、エラー条件がマスクされる可能性がまったくなく式を介して伝搬する値だからです。
他のノードで発生する例外 (つまり、PROPAGATE ステートメントのダウンストリーム) は、ハンドラーによって通常の方法でキャッチされます。 ただし、このようなエラーをふさわしく処理しようとすると、問題が生じます。つまり、元のエラーに別のノードが関係していたため、別のノード (例外の発信元であるとは限らない) がエラーの処理に関係している可能性が非常に高いのです。
このような状態で役立つよう、Database および Compute ノードには、Out1、Out2、Out3、および Out4 という 4 つのターミナルが用意されています。 さらに、PROPAGATE ステートメントの構文には、ターゲット式、メッセージ・ソースおよび制御の文節が組み込まれ、これらのターミナルをより良く制御できるようになりました。