我正在尝试学习SQL Service Broker(SSB),我首先要阅读MSDN上的一些简单教程。我在看“Completing a Conversation Between Databases”。请求和回复消息在启动器和目标数据库上设置,两个dbs上都有使用这些消息的合同,使用队列的启动器数据库上的服务,以及使用队列和合同的目标上的服务。
启动器向目标服务发送消息,开始对话。目标收集此消息并发送回复(并调用END CONVERSATION
),最后发起人选择回复并调用END CONVERSATION
。
如果我现在在Initiator上执行SELECT * FROM sys.conversation_endpoints
,则不返回任何行。但是,目标数据库返回了一行;对话处于CLOSED
状态。
这是正确的(即目标数据库是否仍然存储此对话)?如果没有,我如何摆脱目标数据库上的对话?如果它是正确的,这些对话什么时候消失?
这是目标数据库获取请求并发送回复的代码:
DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER;
DECLARE @RecvReqMsg NVARCHAR(100);
DECLARE @RecvReqMsgName sysname;
BEGIN TRANSACTION;
WAITFOR
( RECEIVE TOP(1)
@RecvReqDlgHandle = conversation_handle,
@RecvReqMsg = message_body,
@RecvReqMsgName = message_type_name
FROM TargetQueue2DB
), TIMEOUT 1000;
SELECT @RecvReqMsg AS ReceivedRequestMsg;
IF @RecvReqMsgName =
N'//BothDB/2DBSample/RequestMessage'
BEGIN
DECLARE @ReplyMsg NVARCHAR(100);
SELECT @ReplyMsg =
N'<ReplyMsg>Message for Initiator service.</ReplyMsg>';
SEND ON CONVERSATION @RecvReqDlgHandle
MESSAGE TYPE
[//BothDB/2DBSample/ReplyMessage] (@ReplyMsg);
END CONVERSATION @RecvReqDlgHandle;
END
COMMIT TRANSACTION;
GO
答案 0 :(得分:1)
为了防止重放攻击,目标端点会被延迟30分钟删除。是否在CLOSED端点上设置了sys.conversation_endpoint.security_timestamp
?
答案 1 :(得分:0)
除了Remus之外的进一步说明:如果对话无法正常完成,它仍然可以显示在sys.conversation_endpoint
之外的security_timestamp
。在这种情况下,您可以使用唯一标识符sys.conversation_endpoint.conversation_handle
(即94798AB6-DF37-E211-BF0F-002215A14A37)手动删除对话:
END CONVERSATION conversation_handle WITH CLEANUP
WITH CLEANUP
很重要,请参阅MSDN:END CONVERSATION (Transact-SQL)