Sql server SQL Server Service Broker队列对话对话框
我和ServiceBroker合作了几个星期,在追踪一次对话时,我发现了一些奇怪的事情。。。对话结尾的队列中似乎有一条额外的消息,这也会导致错误发生 据我所知,对话对话框应如下所示: 触发火灾和呼叫开始对话 启动器服务将消息放置在队列上 目标服务触发存储的进程,接收消息并结束对话 启动器服务触发存储的进程,接收消息,并结束对话。 发生的情况是,队列末尾有一条额外的消息再次触发存储的进程,但详细信息(即会话句柄)为空。它还抛出一个错误:从字符串转换为uniqueidentifier时转换失败。为了避免这个错误,我将会话句柄转换为varchar,然后检查null。我觉得我必须这么做很愚蠢 更新:错误已经消失了-我相信这是在我试图记录为空的对话句柄时发生的 什么是结束对话的正确方式,而不在最后得到额外的信息 以下是我现在拥有的:Sql server SQL Server Service Broker队列对话对话框,sql-server,service-broker,Sql Server,Service Broker,我和ServiceBroker合作了几个星期,在追踪一次对话时,我发现了一些奇怪的事情。。。对话结尾的队列中似乎有一条额外的消息,这也会导致错误发生 据我所知,对话对话框应如下所示: 触发火灾和呼叫开始对话 启动器服务将消息放置在队列上 目标服务触发存储的进程,接收消息并结束对话 启动器服务触发存储的进程,接收消息,并结束对话。 发生的情况是,队列末尾有一条额外的消息再次触发存储的进程,但详细信息(即会话句柄)为空。它还抛出一个错误:从字符串转换为uniqueidentifier时转换失败。为了
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
没有任何额外的信息。只是在一个空队列上激活了您的过程。您激活的过程代码应该期望被激活并接收,以便不时返回一个空行集。如果您每次仅使用一条消息进行测试,则每次都会发生,正如您所观察到的,在实际负载下很少发生
在您的代码中,这种情况下接收空结果集将反映在NULL@handle、NULL@messageType和NULL@responseXML中,这与您描述的非常相似。您的恶意消息的消息类型是什么?