处理 Service Broker 错误消息

Service Broker 应用程序必须处理从会话中收到的两类错误消息:使用 Service Broker 的应用程序创建的错误消息和 Service Broker 创建的系统消息。

报告应用程序错误条件

Service Broker 应用程序通常为由不同计算机上异步运行的代码组成的系统。应用程序的组成部分通过使用在 Service Broker 会话上发送的消息彼此通信。Service Broker 会话一端的应用程序组成部分可以通过向另一端发送错误消息来报告应用程序错误。应用程序的接收部分必须通过代码来检测错误消息并正确处理错误条件。

Service Broker 应用程序可以通过使用系统定义或应用程序定义的消息类型通知错误。

系统定义的错误消息

使用 END CONVERSATION 语句的 WITH ERROR 子句报告严重到足以需要结束会话的应用程序错误。例如:

END CONVERSATION @ConversationHandle
    WITH ERROR = 1234 DESCRIPTION = "The account specified in the invoice does not exist, verify the account number."

END CONVERSATION WITH ERROR 语句:

应用程序接收 Error 消息的部分应执行任何所需的清除操作并结束其会话端。

应用程序随时可以结束出错的活动会话。但是,如果会话的远程端已结束了会话,则 Service Broker 将不会向远程端发送错误消息。Service Broker 将改为只结束会话的本地端并从本地队列删除会话的所有消息。

应用程序定义的错误消息

可以使用应用程序定义的错误消息报告严重性不足以结束会话的错误。应用程序设计器可以指定下列方面:

  • 用于通知这些应用程序错误的一个或多个消息类型。

  • 用于处理这些消息类型的逻辑。

遇到错误条件的应用程序部分可以执行以下操作:

  • 执行会话本地端所需的任何清理操作。

  • 使用应用程序定义的消息类型生成一条消息并在会话中发送该消息。

收到错误消息的应用程序远程部分必须利用代码识别该错误消息并在其连接端上执行所需的任何清理操作。

处理错误消息

从 Service Broker 会话收到消息的应用程序代码必须利用逻辑处理从会话收到的错误消息。该代码必须检测并处理以下错误消息:

  • 使用应用程序定义错误消息类型的应用程序生成的错误消息。

  • 使用 END CONVERSATION 语句的 WITH ERROR 子句的应用程序生成的错误消息。这些错误消息使用 https://schemas.microsoft.com/SQL/ServiceBroker/Error 消息类型并在 Code 元素中具有正数。

  • Service Broker 生成的错误消息。这些错误消息使用 https://schemas.microsoft.com/SQL/ServiceBroker/Error 消息类型并在 Code 元素中具有负数。当因某个错误而使 Service Broker 无法继续会话时,Service Broker 将创建一个 Error 消息。例如,Service Broker 无法找到目标服务,因为该服务在当前实例中不存在并且路由表中没有该服务的条目。在此情况下,Service Broker 将为会话创建一条 Error 消息。

RECEIVE 语句返回的结果集包含一个 message_type_name 列。收到 Service Broker 消息的代码通常使用 message_type_name 将每条消息路由至处理相关消息类型的代码。

程序处理错误所遵循的准确逻辑取决于该应用程序。一个示例为使用消息保持期并在任务失败时需要补偿事务的程序。收到错误后,程序会在队列中查询该消息是否已得到处理并执行补偿事务,然后结束该会话。与此相反,如果该程序只需记录发生的错误,则程序将错误记录至日志记录表并结束该会话。

https://schemas.microsoft.com/SQL/ServiceBroker/Error 消息的 Code 元素包含错误代码。使用 END CONVERSATION WITH ERROR 的应用程序创建的 Error 消息具有错误代码的正值。Service Broker 生成的 Error 消息包含错误代码的负值。Service Broker 生成的消息中的 Code 值恰好为导致 Error 消息的错误的负值。例如,发生 XML 验证错误(错误代码 9615)时,数据库引擎 会创建一个 Error 消息,该消息具有包含值 -9615Code 元素。

一旦应用程序收到一条 Error 消息,该程序便不能再在该会话中发送消息。应用程序将处理该错误,然后结束其会话端。如果应用程序收到一个应用程序定义的错误消息类型,除非应用程序的远程部分也运行 END CONVERSATION,否则该会话仍然可用。

应按照与防范有害消息相同的方式编写错误处理例程的代码。有关详细信息,请参阅处理有害消息