SQL Server Service Broker错误处理

Rus*_*ark 3 sql-server sql-server-2005 service-broker

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

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

Rem*_*anu 20

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

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

当SEND可以返回一个错误的唯一情况是当无法邮件发送,而不是当它不能交付.如果您尝试进行SEND已关闭的对话,或者存在某些非代理错误(只读数据库,日志已满,内存不足等),则会阻止甚至接受该消息sys.transmission_queue.

甚至本地传递异步和松散耦合的这种行为是有意的,旨在通过在目标队列是本地的以及目标队列是远程时表现相同来帮助应用程序.

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

因此,在您禁用代理的情况下,仍然会接受消息,但不会传递消息.它被放置在transmsision队列中.只要在数据库中启用代理,就会拾取并传递该消息.当交付的可靠性是主要关注点时,此行为使应用程序编写更加简单.即使目的地不可用(例如,用于服务维护),应用程序也只是发送消息即使消息将会到达那里,即使消息传递需要数小时,数天甚至数周.对于与交付时间有关的应用程序,它们应指定对话生存期.系统将尝试在此生命周期内传递消息或放弃.如果它放弃,它会通过排队错误消息(会话超时错误)通知发件人.

应用程序也不应该等待响应.他们应该SEND,COMMIT并且继续,是事件驱动的.当目标发回响应时,或者当底层基础结构通知错误时,应用程序在其自己的队列中获取消息,并且它应该对该消息作出反应.