【发布时间】:2010-08-10 10:28:44
【问题描述】:
我们最近发现我们的一个数据库存在问题,由于设置了“即发即弃”(即:会话在发送后立即关闭),我们的 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 似乎表明它是一个错误,并且运行清理剩余物的作业是唯一的解决方案...
更新: Pawel 在下面指出,我应该避免使用 Fire & Forget 模式,并且我已将激活的 SP 添加到发起者队列以结束任何对话。但是,sys.conversation_endpoints 仍然被填满,这次是 CD/CLOSED 消息。这是我的队列结构
发送_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;
【问题讨论】:
标签: sql-server sql-server-2008 service service-broker