Service Broker is not a black box. SQL Server Service Broker Basics Part One was designed to support your messaging needs and make sense of Service Broker.
SQL Server Service Broker Basics Part One
I’m currently implementing a SQL Server Service Broker solution at a client site, and it’s been an interesting challenge, because there’s not a lot of information out there to help guide you through the process. Here I’d like to walk you through the basics.
Message Types. Service Broker sends messages asynchronously from one database to another. You can set it up to send messages between databases on a single server, or between SQL Server instances on a Windows server, or between different physical servers, whether or not they’re in the same domain. Essentially Service Broker works at the database level, the rest is handled through routing, which I’ll address in another post.
The important thing to remember is that Service Broker sends and receives messages, and then your applications (or stored procedures) handle those messages in some way. It handles them asynchronously, so the sending side doesn’t have to wait for the receiving side to acknowledge the message, and it handles them sequentially, so the messages will always arrive in the order in which they’ve been sent.
Many of the examples you’ll see use message types like “REQUESTMESSAGE” and “REPLYMESSAGE”. To me this is a disservice, because it doesn’t help you see the different ways you can use Service Broker to solve your business problems. At my client site the message types indicate the content of the message, so the receiving side can use the type to determine the action to take when the message is received. Service Broker has a built-in acknowledgement process, so you don’t need to specifically acknowledge a message, unless the application needs it. As long as the communication channels are open, the message will be delivered.
CREATE MESSAGE TYPE [//AWSync/Sync/HumanResourcesEmployee] AUTHORIZATION dbo VALIDATION = WELL_FORMED_XML GO
Contracts. Once you’ve defined the types of messages that can be sent, you need to define how they’ll be delivered. Contracts define what message types are allowed to be sent, and in which direction. This means that Service Broker is secure in that it won’t process any messages types not defined in a contract, so rogue processes that attempt to try a type of SQL Injection attack against Service Broker will fail.
CREATE CONTRACT [//AWSync/Sync/IntContract] AUTHORIZATION dbo ( [//AWSync/Sync/HumanResourcesEmployee] SENT BY ANY, [//AWSync/Sync/PersonContact] SENT BY ANY, [//AWSync/Sync/PurchasingVendor] SENT BY ANY ) GO
Queues. Once the contract is defined, you can define the queue on which the messages are sent and received. The queue also defines (if you want) an automated process that will handle the messages it receives. In your Transact-SQL code you retrieve messages from the queue in the same way you read data from a table – in fact, the queue behaves just like a table in your database.
CREATE QUEUE IntQueue WITH STATUS = ON, RETENTION = OFF GO
Services. The service is the glue which assigns the contract to the queue. It performs the work of actually sending the messages on the queue to their destination and receiving the messages coming from other senders.
CREATE SERVICE [//IntSite/Sync/IntService] AUTHORIZATION IntUser ON QUEUE IntQueue ([//AWSync/Sync/IntContract]) GO
Conversations. In its simplest form, the last thing we need is to send the message. We do that via a conversation, which is referred to in Service Broker as a DIALOG CONVERSATION or simply a DIALOG. You specify the source and destination service name, and a conversation handle (a GUID) is returned, then you SEND ON CONVERSATION using that conversation handle. The message body is usually in an XML form, and for security purposes should be encrypted.
BEGIN DIALOG @InitDlgHandle FROM SERVICE [//IntSite/Sync/IntService] TO SERVICE N'//ExtSite/Sync/IntService' ON CONTRACT [//AWSync/Sync/IntContract] WITH ENCRYPTION = ON; SEND ON CONVERSATION @InitDlgHandle MESSAGE TYPE [//AWSync/Sync/HumanResourcesEmployee] (@ChangeMsg);
Finally, you need to be able to receive the messages. Like I mentioned earlier, reading from a queue is like reading from a table, but there are some additional features in Transact-SQL to facilitate message handling. Specifically, there’s a special form of the WAITFOR command which will wait for either the arrival of a message, or timeout after a specified number of milliseconds.
WAITFOR ( RECEIVE TOP(1) @ch = conversation_handle, @service_name = service_name, @service_contract_name = service_contract_name, @messagetypename = message_type_name, @messagebody = CAST(message_body AS XML) FROM ExtQueue ), TIMEOUT 60000
With these components you can set up messaging within a single instance of SQL Server. In my next post I’ll discuss the additional plumbing required to communicate between separate instances.
Reprinted with author’s permission from SQLBlog.com.