服务经纪人队列正在禁用自己,无法发掘原因

时间:2013-03-29 15:27:41

标签: sql sql-server service-broker

在sys.transmission_queue中,我给出的唯一信息是“一个或多个消息无法传递到此对话框所针对的本地服务。”

如果我重新启用其中一个问题队列(有五个)并将“激活”设置为“关闭”,则队列将填充其消息。如果我然后运行激活SP,我正确处理消息,没有问题。但是一旦我打开激活,如果队列中有任何消息,队列将再次禁用它们。

我完全迷失了。有谁知道我怎么解决这个问题?

2 个答案:

答案 0 :(得分:10)

队列禁用自己作为对poison message handling protection的反应。这意味着您的激活过程正在回滚,可能是由于某些异常。激活的过程没有会话发送错误,因此他们将其发送到ERRORLOG。检查您的错误日志,应该包含来自您激活的程序的错误消息。

最简单的故障排除方法是在激活关闭时从SSMS手动运行激活的程序。尝试重新创建与激活相同的执行上下文,请参阅Internal Activation Context。关键部分是EXECUTE AS上下文,它改变了很多行为,特别是安全性。所以试试这个(假设你的队列在dbo下执行):

use <dbname>;
go

execute as user = 'dbo';
go

exec <sp_my_activated_proc>;
go

revert;
go

您可能会收到一条错误消息,可能是您重复禁用的原因。

答案 1 :(得分:0)

我会假设我正在处理此毒药信息。

队列在第一条消息后禁用 发生在2008年和2012年。 但是在我的开发PC上使用2008 r2

工作得很好

但是,“SQL Server日志”

中没有显示任何内容

如果我创建没有激活子句的队列并手动运行SQL,则SP运行并返回而没有错误(日志中也没有任何内容),并且队列禁用

如果我设法找出原因,我会更新。

消息中毒 - 连续5次回滚后无声失败。

从来没有找到任何日志,但原因是我的NULL检查:

WAITFOR
(
    RECEIVE TOP(1)
        @msg        = convert(xml,message_body),
        @DlgId      = conversation_handle
    FROM dbo.AuditLog_Request_Queue
), TIMEOUT 1000;

-- exit when waiting has been timed out
IF @@ROWCOUNT = 0
BEGIN
    IF @@TRANCOUNT > 0
    BEGIN
        ROLLBACK TRANSACTION;
    END
    BREAK;
END

-- exit when waiting has been timed out
IF @msg IS NULL
BEGIN
    IF @@TRANCOUNT > 0
    BEGIN
        ROLLBACK TRANSACTION;
    END
    BREAK;
END

将其移到后面的EXECUTE语句中会停止问题