内部错误可能是由程序在数据库中存储了无效数据或者是由于流的逻辑中存在缺陷导致的。
处理 ESQL 错误最简单的策略就是不执行任何操作并使用代理的缺省行为。缺省行为是中止失败消息的处理并继续处理下一条消息。输入节点和输出节点提供用于控制中止处理时将发生的具体情况的选项。
这些策略中的每一个都具有其优势。事务方式保留数据的一致性,而非事务方式则能最大限度地连续处理消息。请记住,在事务方式中,失败的输入消息被放回到输入队列,代理将再次尝试处理它。此方式最可能的结果是,消息持续失败,直到达到重试限制,此时消息被放入死信队列。处理消息失败的原因被记录到系统事件日志(Windows)或 syslog(UNIX)。因此,失败消息将使后续正常消息的处理有所延迟,然后代理将使它保持未处理的状态。
大多数数据库都以事务方式运行,这样当消息处理成功时,将落实对数据库表作出的所有更改,处理失败时则回滚这些更改,从而保持数据的完整性。此情况的一个例外是,当代理本身或数据库失败时。(例如,运行代理或数据库的机器的电源可能中断。)在这些情况下,有可能有些数据库中的更改落实了,其他一些数据库中的更改则没有落实;或者数据库更改将落实,而输入消息和输出消息则不会落实。如果您担心发生这些可能情况,则应该对流进行协调并针对这种工作方式配置所涉及的数据库。
使用 failure 终端捕获未处理的错误。 将简单逻辑流连接到 failure 终端。此逻辑流可能由数据库或计算节点组成,计算节点将日志记录写至数据库(可能包含消息的位流)或将记录写至事件日志。它还可能包含将消息写至特殊队列的输出节点。
整个异常树将被传递到连接到 failure 终端的任何节点。(异常树在 ExceptionList 树结构中有所描述。)
有关可以用来处理消息流中错误的选项的详细讨论,请参阅处理消息流中的错误。以下主题提供了您可执行的操作的示例:
语句构成上无效的输入消息(以及由于错误的消息格式信息而显示为无效的输入消息)很难处理,这是因为代理不知道该消息包含什么内容。很可能处理它们的最好的方法就是配置输入节点来完全解析和验证消息。
但是,请注意这仅适用于预定义的消息,即 MRM 或 IDOC。
要处理失败的消息,请将简单逻辑流连接至 failure 终端。
此策略的唯一缺点就是,如果常规流不要求对所有消息字段的访问权,则强制完成消息解析将会影响性能。
如果您需要比缺省错误处理更好的方法,第一步就是使用处理程序(请参阅 DECLARE HANDLER 语句)来拦截异常。处理程序可以从数据库返回的 SQL 语句确定故障的性质。
然而,请小心使用这种类型的策略。因为处理程序将吸收异常,所以对其他数据库进行的任何更改或对队列进行的任何写入都将落实。
发生在 MQ output 节点中的错误会在 SQL 语句中报告错误的性质并在 SQL native error 变量中给出其他信息。因此,如果您需要比缺省错误处理更好的方法,第一步就是使用处理程序(请参阅 DECLARE HANDLER 语句)来拦截异常。这种处理程序通常仅围绕单个 PROPAGATE 语句。
在缺少类型约束的情况下,尝试访问不存在的消息字段将产生值 null。Null 值通过表达式传播,使结果为空。因此,无论表达式多么复杂,只要它不返回空值,您就可以知道它所需用来计算其结果的所有值都不为空。
强制类型转换表达式可以具有缺省子句。如果有缺省子句,强制类型转换会毫无动静地失败;它们只返回缺省值,而不抛出异常。缺省值可能是没有害处的数字(例如,对整数使用零),或者在上下文中明显无效的值(例如对客户号使用 -1)。Null 可能特别适用,因为它是一个不同于所有其他值的值,将通过表达式传播而没有任何屏蔽出错条件的可能性。
在其他节点(即,PROPAGATE 语句的下游)中发生的异常可能会被处理程序以常规方式捕获。但如果以巧妙的方式处理这种错误,会造成这样一个特殊问题,当原始错误涉及另一个节点时,在处理该错误时很有可能涉及另一个节点(不一定是异常的发起方)。
为了帮助处理这些情况,数据库节点和计算节点具有四个新的终端,称为 out1、out2、out3 和 out4。另外,已经将 PROPAGATE 语句的语法扩展为包含目标表达式、消息源和控制子句,以对这些额外的终端进行更多控制。