我们最近发现了一个我们的数据库存在问题,其中包括“火灾”和“火灾”。忘记'设置(即:会话在发送后立即关闭),我们的sys.conversation_endpoints表填满了DI / DISCONNECTED_INBOUND消息。这最终蔓延到tempDB中,导致它大量增长并占用宝贵的磁盘空间。我们最终通过注释掉
行解决了这个问题 END CONVERSATION @handle WITH CLEANUP
在我们发送SP并使用相同代码关闭接收SP中的会话
END CONVERSATION @handle WITH CLEANUP
但是,我们现在有了一个新问题。自从移动服务器(以及从SQL Server 2005迁移到SQL Server 2008)以来,我们最近发现sys.conversation_endpoints现在正在填充CO / CONVERSING消息,表明对话没有被关闭。接收SP正在关闭它们,或者至少运行命令来执行此操作,因此我不明白这些消息来自何处。
我已经尝试在发送时回去结束对话,但它没有效果。使用WITH CLEANUP
结束接收端的会话是错误的吗?还是有其他问题吗?
这post on techtarget似乎表明它是一个错误,并且运行清理残羹剩饭的工作是唯一的解决方案......
更新: 帕维尔在下面指出,我应该避开Fire&忘记模式,我已经将激活的SP添加到启动器队列以结束任何对话。但是,sys.conversation_endpoints仍然是STILL填充,这次是CD / CLOSED消息。这是我队列的结构
Send_SP:
DECLARE @h UNIQUEIDENTIFIER
BEGIN DIALOG CONVERSATION @h
FROM SERVICE 'InitiatorQueue' TO SERVICE 'TargetQueue'
ON CONTRACT 'MyContract' WITH ENCRYPTION = OFF;
SEND ON CONVERSATION @h MESSAGE TYPE 'MyMessage' (@msg)
Receive_SP(在TargetQueue上激活SP)
DECLARE @type SYSNAME, @h UNIQUEIDENTIFIER, @msg XML;
DECLARE @target TABLE (
[message_type_name] SYSNAME,
[message_body] VARBINARY(MAX),
[conversation_handle] UNIQUEIDENTIFIER
)
WHILE(1=1)
BEGIN TRANSACTION
WAITFOR(RECEIVE TOP (1000)
[message_type_name],[message_body],[conversation_handle]
FROM TargetQueue INTO @target), TIMEOUT 2000
IF(@@rowcount!=0)
BEGIN
WHILE((SELECT count(*) FROM @target) > 0)
BEGIN
SELECT TOP (1) @type = [message_type_name],
@msg = [message_body],
@h = [conversation_handle] FROM @target;
// Handle Message Here
END CONVERSATION @h;
DELETE TOP (1) FROM @target;
END
END
COMMIT TRANSACTION;
End_SP(在InitiatorQueue上激活SP)
DECLARE @type SYSNAME, @h UNIQUEIDENTIFIER, @msg XML;
DECLARE @init TABLE (
[message_type_name] SYSNAME,
[message_body] VARBINARY(MAX),
[conversation_handle] UNIQUEIDENTIFIER
)
WHILE(1=1)
BEGIN TRANSACTION
WAITFOR(RECEIVE TOP (1000)
[message_type_name],[message_body],[conversation_handle]
FROM InitiatorQueue INTO @init), TIMEOUT 2000
IF(@@rowcount!=0)
BEGIN
WHILE((SELECT count(*) FROM @init) > 0)
BEGIN
SELECT TOP (1) @type = [message_type_name],
@msg = [message_body],
@h = [conversation_handle] FROM @init;
END CONVERSATION @h;
DELETE TOP (1) FROM @init;
END
END
COMMIT TRANSACTION;
答案 0 :(得分:1)
使用“即发即忘”模式将不可避免地导致此类和其他类型的问题。此外,它将使任何假设错误都不被注意。是否有任何理由不能更改消息交换模式,以便目标在收到消息后发出END CONVERSATION(无需清除!),然后发起者在接收到结束对话消息时仅调用END CONVERSATION(再次,不进行清理)从目标?