|  | 级别: 初级 IBM,
2003 年 7 月 01 日 本文通过从异常列表中抽取诊断信息的代码来分析讲解WebSphere MQ Integrator Broker 2.1中是如何处理异常的。
ESQL 代码片断
从异常列表中抽取诊断信息的代码。为了说明清楚,我们提供了适当的注释。注释由“--”开始。
-- Enter SQL below this line. SQL above this line might be regenerated,
-- causing any modifications to be lost.
-- This Variable determines whether Specific or General Diagnostic
-- Information is generated.
DECLARE IsSpecific Boolean;
-- Can be dynamically set using the Environment Variable.
SET IsSpecific = True;
DECLARE I Integer;
DECLARE J Integer;
SET J = CARDINALITY("InputRoot".*[]);
SET I = 1;
-- Copying(Properties,MQMD,other headers) the Message Tree except for
-- the Body to the Output.
While I < J do
SET OutputRoot.*[I] = InputRoot.*[I];
SET I=I+1;
End While;
-- Sets the Output Diagnostic Message's Format to be XML.
SET "OutputRoot"."Properties"."MessageFormat" = 'XML';
SET OutputRoot.MQMD.Expiry = -1;
-- Source of the message, which caused the error.
SET OutputRoot.XML.Error.MessageSource.QueueManager =
"InputRoot".MQMD.ReplyToQMgr;
SET OutputRoot.XML.Error.MessageSource.Queue =
"InputRoot".MQMD.SourceQueue;
-- If isSpecific is True Specific Diagnostic Information is Generated.
If IsSpecific = True then
-- Point to the First Child to the ExceptionList Root.
DECLARE Location character;
DECLARE Diagnostics character;
DECLARE DiagnosticsInfo character;
DECLARE Width Integer;
SET Width = 1;
DECLARE Path REFERENCE TO InputExceptionList.*[Width];
-- Check whether the Width of the Exception Tree is more and Proceed.
While LastMove(Path) do
SET Diagnostics = '';
SET DiagnosticsInfo = '';
While FieldName(Path) = 'RecoverableException' or FieldName(Path) =
'DatabaseException' or
FieldName(Path) = 'ConversionException' or FieldName(Path) =
'ParserException' or FieldName(Path) = 'UserException'
do
IF Length(Path.Label) > 0 THEN
SET Location = Path.Label;
End if;
IF Length(Path.Text) > 0 THEN
SET Diagnostics = Diagnostics || Path.Text || '. ';
End if;
MOVE Path Lastchild;
End while;
-- Construct the Specific Diagnostic Message.
MOVE Path Parent;
-- Determine the source of message which caused the error.
SET OutputRoot.XML.Error.Detail[Width].ExceptionType = FieldName(Path);
SET OutputRoot.XML.Error.Detail[Width].ErrorNumber = Path.Number;
SET OutputRoot.XML.Error.Detail[Width].SeverityLevel = Path.Severity;
SET OutputRoot.XML.Error.Detail[Width].ErrorSource = Location;
SET OutputRoot.XML.Error.Detail[Width].DiagnosticMessage= Diagnostics;
MOVE Path FirstChild;
-- while loop included to generalize coding to ensure future
-- compatiblity in case of change in tree structure and to move
-- the insert's Field.
While FieldName(Path) <> 'Insert' do
MOVE Path NextSibling;
End while;
-- while loop to traverse all the inserts and construct the
-- additional diagnostic
message.
While LastMove(Path) do
IF Length(Path.Text) > 0 THEN
SET DiagnosticsInfo = DiagnosticsInfo || Path.Text || '. ';
End if;
MOVE Path NextSibling;
End while;
SET OutputRoot.XML.Error.Detail[Width].CauseOfError = DiagnosticsInfo;
SET OutputRoot.XML.Error.Detail[Width].MessageState =
cast(bitstream(InputBody) as CHAR ccsid 437);
SET Width = Width +1;
MOVE Path TO InputExceptionList.*[Width];
End while;
-- Else part to generate diagnostic message which has the structure
-- of all the trees as
when the exception had occured
else
SET I = 1;
While I < J do
SET OutputRoot.XML.Error.*[I] = InputRoot.*[I]; SET I = I + 1;
End while;
SET OutputRoot.XML.Error.Environment = Environment;
SET OutputRoot.XML.Error.LocalEnvironment = InputLocalEnvironment;
SET OutputRoot.XML.Error.MessageState =
cast(bitstream(InputBody) as CHAR ccsid 437);
SET OutputRoot.XML.Error.ExceptionList = InputExceptionList;
End if;
SET OutputRoot.XML.Error.TimeStamp =
SUBSTRING(CAST(CURRENT_TIMESTAMP AS CHAR) FROM 12 FOR 23);
-- Flag set to Indicate Exception processing has occured in the flow.
SET Environment.Variables.ErrorFlag = 'Y';
|
建议
进一步增强
这是一些在灵活使用子流时很有用的提示。
- 把子流附加至 MQInput 节点的捕获节点是很合理的,因为错误处理路径将会退回这个节点,并因此可以处理未被专门捕获和处理的异常。
- 对于象 Compute、Extract 和 ResetContentDescriptor 这些可以修改消息内容的节点而言,您应该在这些节点前附加一个 TryCatch 节点。您需要这样做来获取异常发生之前消息的状态。
- 只要有可能出现业务异常(如 Database 节点中的数据库处理),最好使用消息流中特定级别的错误处理程序并捕获特定的诊断消息。
- 在消息的状态对诊断异常不是十分重要的情况下,错误处理程序子流无需被附加到特定级别的消息流。未经特别处理的异常将在输入节点级别被捕获和处理。
- 对错误处理程序子流的其他改进就是将业务或应用程序异常(分析异常、数据库异常、转换异常和用户抛出异常)从系统异常中分离出来(MQqueue 和其他 MQ 对象无法实现)。实现这一点的方法是:通过添加过滤节点,把应用程序异常路由至一个输出队列,并把系统异常路由至另一个队列。
- 该子流的进一步增强可以通过增加一些消息治疗技术来完成。消息治疗(Message Hospital)指改正错误消息并将它们返回到输入队列中进行处理的过程。改正输入消息中的错误的逻辑取决于业务需要,必须特别处理。
关于作者  | |  | IBM has authored this article |
对本文的评价
|  | IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。 |