【问题标题】:SQL Server Service Broker Error HandlingSQL Server 服务代理错误处理
【发布时间】:2009-09-30 16:25:56
【问题描述】:

我有一个将消息放入 SQL Server Service Broker 消息队列的存储过程。如果出现问题并且消息没有放在消息队列中,我需要从存储过程返回错误消息。我看到的问题是,即使禁用了 SQL Server 服务代理(这是我试图测试将消息放入队列失败的方式),当我运行 TSQL 代码放置时它不会返回错误队列中的一条消息。

有谁知道如何检测将消息放入 SQL Server Broker 消息队列是否失败?

【问题讨论】:

    标签: sql-server sql-server-2005 service-broker


    【解决方案1】:

    Service Broker 不会将消息放入目标队列。而是放入数据库传输队列 (sys.transmission_queue)。在提交 SEND 后,消息被后台发送器拾取,路由被解析并将消息传递到其目的地。

    如果目标恰好位于同一实例中,则在 SEND 语句本身期间尝试使用快捷传递路径,其中消息直接放入目标队列中。如果入队失败,则将消息退回并放置在正常的传递路径中,即。放入sys.trasnmission_queue。卡在sys.transmission_queue 中的消息将有一个transmission_status 解释无法传递消息的原因。系统将自动重新尝试这些消息。

    SEND 可以返回错误的唯一时间是消息无法发送,而不是消息无法传递。如果您尝试在已关闭的对话中使用SEND,或者如果存在一些非代理错误(只读数据库、日志已满、内存不足等),甚至无法将消息接收到sys.transmission_queue,就会出现这种情况。

    这种将本地传递设为异步和松散耦合的行为是有意为之,旨在帮助应用程序在目标队列为本地时和目标队列为远程时表现相同。

    在 Service Broker 中处理错误的方法是检查您自己的队列以获取响应。如果目标服务主动拒绝您的消息(即访问被拒绝、XML 格式错误或违反服务合同),那么它将以错误结束对话,并且您会在自己的队列中返回一条错误消息。如果您的消息根本无法传递,那么它将保留在传输队列中,直到它过期,然后对话以错误结束,并且再次将错误消息放入您自己的队列中。消息在BEGIN CONVERSATION 指定的生命周期到期后超时。

    因此,在您禁用代理的情况下,消息仍被接受,但未传递。它被放置在传输队列中。一旦您在数据库中启用代理,该消息将被拾取并传递。当交付的可靠性是主要关注点时,这种行为使应用程序编写更加简单。即使目的地不可用(例如,因服务维护而停机),应用程序只是发送知道消息到达那里,即使消息需要数小时或数天甚至数周才能发送发表。对于还关心交付时间的应用程序,它们应该指定会话生命周期。系统将尝试在此生命周期内传递消息或放弃。如果它放弃了,它会通过排队一个错误消息(会话超时错误)来通知发送者。

    此外,应用程序不应等待响应。他们应该SENDCOMMIT 并继续,事件驱动。当目标发回响应时,或者当底层基础架构通知错误时,应用程序会在其自己的队列中获取一条消息,并且它应该对该消息做出反应

    【讨论】:

    • 你好莱姆斯。在发送失败的情况下,例如尝试发送格式错误的 XML 时,传输状态为“Service Broker 在此会话中收到错误消息。 Service Broker 不会传输消息;它将一直保留到应用程序结束对话'。有没有办法识别队列中的此类消息?我的自动发件人队列将它们作为普通邮件处理..
    • @milez 请提出一个单独的问题
    猜你喜欢
    • 1970-01-01
    • 2016-06-17
    • 2011-09-20
    • 1970-01-01
    • 2013-10-19
    • 2015-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多