【问题标题】:Service Broker queue rollback on receive接收时 Service Broker 队列回滚
【发布时间】:2017-08-15 20:00:49
【问题描述】:

使用基于here的基础

Service Broker 提供自动中毒消息检测。如果从队列接收消息的事务回滚五次,则自动有害消息检测会将队列状态设置为 OFF。此功能可防止应用程序无法以编程方式检测到的灾难性故障。

我有一个 Windows 服务应用程序,它轮询 SB 队列并将它们发送到 Web 服务端点。因为,我应该处理任何“服务器关闭”问题─将消息返回到队列,所以我包括“队列项目接收”和“队列项目发送”方法进入同一笔交易。在第一个异常 (HttpRequestException) 上,我开始 ping 服务器以获得预定义的超时,然后继续/关闭程序。

但是,回滚五次是一个问题,我知道无论 5 次连续回滚之间的时间间隔如何,它总是会全局增加回滚计数,因此最终将禁用队列。我说得对吗?队列是否有将回滚计数归零的超时?

如果这是这种行为,是否最好从事务中排除“队列项目发送”方法? 如果我这样做,我应该遵循这样的方法,在异常情况下将消息保存在另一个资源(表、文件)中以便稍后发送,或者其他替代方案...

using tables as queues 如何让我的事务保持统一并摆脱 SB 的回滚问题?它会像SB一样可靠吗?

【问题讨论】:

    标签: sql-server service-broker


    【解决方案1】:

    AFAIK,在具有POISON_MESSAGE_HANDLING = ON 的队列上连续 5 次回滚同一消息将禁用队列,无论时间间隔如何。

    您是否考虑过简单地关闭队列的有害消息处理?然后,您的应用程序有责任区分真正的有害消息(永远无法成功处理的消息)与外部服务依赖关系的问题。在第一种情况下,您可以在其他地方记录问题消息并提交而不是回滚。

    还有其他模式可以使用,例如重新排队消息和提交,但很大程度上取决于是否必须按顺序处理消息。

    【讨论】:

    • 谢谢丹。我需要处理并将消息返回队列的唯一异常是“网络相关”http异常。在处理程序内部,我已经以超时方式处理它,然后关闭程序以避免无限循环。我不知道队列上的毒消息处理关闭,所以如果我禁用它,我可以放松。您是否建议禁用中毒处理或将中毒消息保留在另一个资源中以供以后处理并提交?顺便说一句,订单(FIFO)对我来说很重要。
    • @ibubi,在这种情况下,我只会禁用有害消息处理,并在重试之间等待一段合理的时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 2015-02-28
    • 2012-08-01
    相关资源
    最近更新 更多