I’m trying to learn SQL Service Broker (SSB), and I’m starting by going through some simple tutorials on MSDN. I’m looking at “Completing a Conversation Between Databases“. Request and Reply Messages get set up on an Initiator and a Target database, there’s a Contract on both dbs using these messages, a Service on the Initiator db that uses a Queue, and a Service on the Target that uses a Queue and the Contract.
The Initiator sends a message to the Target Service, beginning a dialog. The Target picks up this message and sends a reply (and calls END CONVERSATION), and finally the Initiator picks up the reply and also calls END CONVERSATION.
If I now do SELECT * FROM sys.conversation_endpoints on the Initiator, no rows are returned. However there is a row returned on the Target database; the conversation is in a CLOSED state.
Is this correct (i.e. should the Target db still be storing this conversation)? If not, how do I get rid of the conversation on the Target db? If it is correct, when do these conversations disappear?
This is the code for the Target db picking up the request and sending the reply:
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
The target endpoints are removed with a 30 minutes delay in order to prevent replay attacks. Is
sys.conversation_endpoint.security_timestampset on the CLOSED endpoints?