我几周来一直在与Service Broker合作,在跟踪对话时,我发现了一些奇怪的事情......对话似乎在队列中有一条额外的消息,这也会导致错误发生。< / p>
根据我的理解,对话对话框应如下所示:
正在发生的事情是队列中有一条额外的消息,它会再次触发存储过程,但细节(即conversation_handle)为空。它还会抛出一个错误:Conversion failed when converting from a character string to uniqueidentifier.
为了解决错误,我将conversation_handle转换为varchar,然后检查null。对我来说似乎很愚蠢,我必须这样做。
更新: 错误已经消失 - 我相信当我尝试记录conversation_handle(无效)时会发生错误。
在没有收到额外消息的情况下结束对话的正确方法是什么?
这就是我现在所拥有的:
alter proc dbo.MessageProcessor
as
begin
set nocount on;
set xact_abort on;
declare @xactState smallint
declare @handle uniqueidentifier,
@responseXml xml,
@messageType sysname;
begin transaction;
begin try
;receive top(1)
@messageType = message_type_name,
@handle = conversation_handle,
@responseXml = message_body
from dbo.MessageQueue
if(@handle is not null)
begin
if (@messageType = N'DEFAULT')
begin
save transaction MessageProcessor_Tran
begin try
-- doing work here
end try
begin catch
select @xactState = xact_state()
if(@xactState = -1)
begin
rollback;
raiserror(N'Unrecoverable error', 16, 1)
end
else if(@xactState = 1)
begin
rollback transaction MessageProcessor_tran
end
-- log error information
end catch
end
else if (@messageType = N'http://schemas.microsoft.com/SQL/ServiceBroker/Error')
begin
declare @errorNumber int,
@errorMessage nvarchar(4000);
with xmlnamespaces (DEFAULT N'http://schemas.microsoft.com/SQL/ServiceBroker/Error')
select @errorNumber = @responseXml.value ('(/Error/Code)[1]', 'INT'),
@errorMessage = @responseXml.value ('(/Error/Description)[1]', 'NVARCHAR(4000)');
-- log error
end
end conversation @handle
set @handle = null
end
commit
end try
begin catch
declare @error int,
@message nvarchar(2048)
select @error = error_number(),
@message = error_message(),
@xactState = xact_state();
if(@xactState <> 0)
rollback;
if(@handle is not null)
end conversation @handle;
-- log error
raiserror(N'Error: %i, %s', 1, 60, @error, @message) with log;
end catch
end
go
答案 0 :(得分:2)
不是任何额外的消息。只是在空队列中激活了您的过程。你的激活程序代码应该被激活,并且RECEIVE会不时地返回一个空的行集(如果你一次只用一条消息来测试它,那么每次都会发生这种情况,正如你所观察到的,在实际负载下它很少会发生) 。
在你的代码中,这样的情况(RECEIVE空结果集)将反映在NULL @ handle,NULL @messageType和NULL @responseXML中,这几乎就是你所描述的。