The Service Broker is a highly scalable message queuing system available directly within the SQL Server 2005 architecture. It essentially provides a messaging system for asynchronous processing of, well, anything really, however, it’s grossly underutilized in the developer community as a whole. The Service Broker solves some common issues with queued systems for you: issues of durability, backups, synchronization, and singularity. I won’t go too much into the detail of how the messaging system works under the hood, the difference between monologs and dialogs, etc., because I want to focus mostly on how you, the developer, can get up and running with the Service Broker as quickly as possible so that you can take advantage of it in your applications. Do the necessary legwork ahead of time to find out if the Service Broker provides a solution to your specific problem. In other words, don’t over-engineer your application to solve a problem you don’t have and don’t expect to have for the foreseeable future. For the purpose of delving deeper into the inner workings of the Service Broker I recommend the readings below:
0. MSDN Article: Typical Uses of Service Broker
1. TechNet Article: Intro to Service Broker
2. MSDN Article: More Service Broker Info
The code samples below will help create messaging communication within a single database. The Service Broker allows for routing communication between multiple databases, physical servers, or instances, however, that is beyond the scope of this writing. Let’s get started by assuming a scenario in which you are writing an application that is commonly disconnected from the Internet and from a central SQL database that stores that applications data. For example, you’re writing an application for an extremely large team of field biologist recording population counts for over 500 species of insects around the world in extremely remote locations. These field biologist have a lap top with an application installed in which you record your data locally. As connectivity permits, the application automatically connects to the central SQL database to synchronize the data of not only your data, but the data of every other biologist in the field. Your charge, as the developer, is to make this application possible using the Service Broker.
Enabling The SQL Server Service Broker
As is the case with the majority of the other SQL Server features, the Service Broker is disabled by default. Let’s first enable the service broker on your testing server. We’ll also create a master key on your test database that will be used as a session key for the Service Broker conversations. Open up SQL Server Management Studio to a testing database of your choice and run the following statements in a new query window:
ALTER DATABASE MyDatabase SET ENABLE_BROKER;
IF NOT EXISTS(SELECT * FROM SYS.SYMMETRIC_KEYS T0 WHERE T0.[NAME] = ‘##MS_DatabaseMasterKey##’)
CREATE MASTER KEY ENCRYPTION BY PASSWORD = ‘123456′;
Message Types and Contracts
Message types and contracts work in much the same way as linguistics. For the Service Broker to be an effective messaging system, we need to define what types of messages will be put into the queue, much like you and I decide on a language when we decide to communicate. Let’s start with the message type. Message types are made up of two key components: name, and validation. The name can really be anything, but you want to be sure to provide something unique. It’s also important to remember that the names are case sensitive. Right now, our purpose is simple: we want to store and process messages on a queue within a single instance of SQL Server and a single database. However, once you get more comfortable with these concepts, you may want to start using the Service Broker as a mechanism for communication between multiple instances, multiple servers, and multiple databases, so you need to ensure uniqueness in your naming conventions. You can easily use a namespace or URI naming convention for this purpose.
You can choose whether or not you want your messages validated as they come into the message queue. All messages are stored with a data type of VARBINARY(MAX), which allows you plenty of rope and 2GB of storage to hang yourself with, so be careful here. For our application, we’re going to use the WELL_FORMED_XML validation type for our messages, which means that our queue will accept any well formed XML document. That should fit our purpose nicely for both the sending and the receiving of messages to our insect population application.
Enough chatter, let’s create the two message types we need for sending and receiving messages into a queue using a simple namespace naming convention:
CREATE MESSAGE TYPE [MyCompany.InsectPop.SendCountData]
VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE [MyCompany.InsectPop.RecieveCountData]
VALIDATION = WELL_FORMED_XML;
Create a Contract
You can think of contracts as the equivalent of an interface in OOP. Contracts are really the heart of any well designed, Service Broker-enabled application because they define how your application can communicate with and derive information from tasks given to the Service Broker. In the case of our insect population application, it could very easily take a while for a user to submit their count data to the database from a remote location with a poor quality Internet connection. You need a way to provide feedback to the user as to the status of their submittal. This is a common problem that needs to be solved in any asynchronous operation, and the Service Broker provides a nice clean way to accomplish this. We’ll delve more deeply into just how this occurs in Part II of this post.
We already have our two send and receive message types defined: InsectPop.SendCountData, and InsectPop.RecieveCountData. Those will be included in the contract since they are part of the logical operation we are trying to achieve. To monitor status, we also need to add a 3rd message type to the contract: InsectPop.CountDataStatus.
CREATE MESSAGE TYPE [MyCompany.InsectPop.CountDataStatus]
VALIDATION = WELL_FORMED_XML;
We’ll also create our contract as follows:
CREATE CONTRACT [MyCompany.InsectPop.InsectCountContract]
(
[MyCompany.InsectPop.SendCountData] SENT BY INITIATOR,
[MyCompany.InsectPop.RecieveCountData] SENT BY TARGET,
[MyCompany.InsectPop.CountDataStatus] SENT BY ANY
);
Let’s paraphrase the code block above to better understand what is going on: the SendCountData message can only be sent by the initiator, which is our application, and the RecieveCountData message can only be received by our target, the service, which we will soon create, and the CountDataStatus message can be sent by either the initiator or the target to check on the status of a queued request.
In Part II of this post we’ll go into more detail about setting up the queues and services that will make our Service Broker application do something useful.
Click here to go to Part II (Coming SOON!)