Service Broker 101 Lesson 3: Conversations and messages
The last post went through the basics of the different components Service Broker uses in SQL Server. I talked about message types, queues that send and receive messages, contracts that specify particular message types to be sent to the target or initiator queue, and services that attach to queues and specify the contracts that can target that queue.
This lesson is all about how we fit these things together to open a conversation and send a message. I’ve seen some other posts that rush through this so I want to take my time with this and go through it step by step.
The first thing we need is an open conversation. This is generated with the BEGIN DIALOG CONVERSATION
statement. Oddly, the CONVERSATION
part is redundant, despite the fact that every other command refers to these items as conversations, not dialogues. Anyway, the command to open a simple conversation is as follows:
DECLARE @ConversationHandle UNIQUEIDENTIFIER;
BEGIN DIALOG CONVERSATION @ConversationHandle
FROM SERVICE [ServiceBrokerExample/Example1/Service/ServiceSource]
TO SERVICE 'ServiceBrokerExample/Example1/Service/ServiceTarget'
ON CONTRACT [ServiceBrokerExample/Example1/Contract/Complicated]
There are a few key things here.
First, each conversation has its own unique dialog_handle (not conversation handle, despite everything calling it a conversation from now on, score one for consistency Microsoft). We need to capture this handle in a UNIQUEIDENTIFIER
variable, as we will need it later on to send messages across the conversation. In fact, the statement will error if you don’t supply a variable to capture the handle.
Second, we need to supply both FROM
and TO
services. These tell the conversation which service is the source and which is the target. Remember, each service is attached to a queue, and can have one or more contracts attached to it. The source service is a database object, but the target service is an NVARCHAR
. This allows the target service to live outside the database, which is something that I will cover at some point in the Service Broker 201 series.
Finally we need to give the contract the conversation will obey. This contract details what message types can be sent by the initiator and target services, and it has to be one of the contracts allowed by the target service.
At this point we have a conversation, and we can start sending messages, the code to do that is below:
SEND
ON CONVERSATION @ConversationHandle
MESSAGE TYPE [ServiceBrokerExample/Example1/MessageType/Reply]
('<message>hello world</message>')
This sends the specified message type across the specified conversation from the initiator to the target. You can also specify the message you want to send in brackets after the message type, but this is not necessary unless the message type forces you to. Sometimes just having a message of a specified type is all the information you need.
Note that the initiator to target rule applies to any code executed in a standard session connected to the database that holds the initiating service. Retrieving a message from the queue, and sending messages from the target to the initiator will be covered in the next session about queues.
The last thing we need to do is close our conversation. To do this we call the END CONVERSATION @ConversationHandle
statement. This sends a message using the inbuilt Microsoft message type http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog
and closes the conversation from one end. To fully close the conversation you need to also call END CONVERSATION
from the other end.
It’s important to always fully close conversations from both ends, otherwise they will hang around eating resources in your database. They may not be much individually, but over time they can add up significantly. A conversation does have a lifetime, specified in seconds, and you can set the lifetime when you create it, but if you don’t the default is 2,147,483,647 (max value of an INT
) which is roughly 68 years.
That’s it for now, hopefully this stuff is starting to come together. The nest session will be all about Queues, how we retrieve these messages from them, how we process the messages once we have them, and how we can send messages back from our target to the initiator.
Trackbacks & Pingbacks