SQL Server Service Broker 2008 Conversation Priorities

Lately, I've been spending some time working with SQL Server 2008. There are a lot of innovative features included in the latest CTP on both the DB and BI engines that are worth checking. I plan to keep blogging about it during the next weeks. On this post I want to focus on what is arguably the biggest improvement on Service Broker (SSB) 2008: conversation priorities.

On the SSB context, Conversation priorities are a set of user-defined rules, each of which specifies a priority level and the criteria for determining which Service Broker conversations to assign the priority level. Normally priority levels determine the order on which messages are sent or receive.

Message queuing prioritization is not exactly a new concept. All the major queued based technologies introduce some level of controlling priorities at the message level. By "at the message level" we mean that given the architecture of most queuing technologies in the market priorities are typically limited only to messages. For instance, technologies like MSMQ or WebSphere MQ assign priorities to messages in order to control the order in which messages are sent or received. What makes service broker approach to this problem unique is the fact that priorities are not only based on messages but also on contract and services.

As part of the current CTP you can use a new Transact-SQL command CREATE BROKER PRIORITY with the following arguments:

  • A name for the conversation priority.
  • A priority level to assign Service Broker conversations. The levels are specified as integers from 1 (lowest) to 10 (highest). The default is 5.
  • The criteria that determine which conversations the priority level applies to the following:
  • A contract name or ANY.
  • A local service name or ANY.
  • A remote service name or ANY.

When an application attempts to receive or send a message, SSB evaluates the priorities based on the best match for the existing local service, remote service and contract. By "best match" we mean that depending on the services and contract involve in a conversation SSB can find multiple priorities that can be applied. For instance, assume a SSB configuration with the following conversation priorities:

  • Priority1(Service1, Service2, Contract1)
  • Priority2(Service1,ANY,ANY)

Based on that configuration, a conversation between Service1 and Service2 based on contract1 match both priorities, however Priotity1 represents a better match compared with Priority2.

Let's take a look to a more complete example of how to use conversation priorities.

Assume that we have the following SSB configuration with three SSB services. Notice that TargetService1 and TargetService2 share the same physical queue.

create queue RequestQueue

create queue ResponseQueue

 

 CREATE MESSAGE TYPE

    [RequestMsgType]

    VALIDATION = WELL_FORMED_XML ;  

   

     CREATE MESSAGE TYPE

    [ResponseMsgType]

    VALIDATION = WELL_FORMED_XML ;

   

CREATE CONTRACT         

    [TestContract]        

    ( [RequestMsgType]        

          SENT BY INITIATOR,        

      [ResponseMsgType]        

          SENT BY TARGET        

    ) ;  

   

CREATE SERVICE InitService

  on queue RequestQueue

  (TestContract);

 

CREATE SERVICE TargetService

  on queue ResponseQueue

  (TestContract);

 

CREATE SERVICE TargetService2

  on queue ResponseQueue

  (TestContract);

In this sample InitService needs to establish conversations with TargetService1 and TargetService2. However, the messages delivered to TargetService2 should take priority over the messages delivered to TargetService1. In order to model the priorities we need to use the CREATE BROKER PRIORITY command assigning a higher priority to the conversation that includes TargetService2.

CREATE BROKER PRIORITY Priority1

    FOR CONVERSATION

    SET (CONTRACT_NAME = TestContract,

         LOCAL_SERVICE_NAME = TargetService,

         REMOTE_SERVICE_NAME = N'InitService',

         PRIORITY_LEVEL = 1);

 

  CREATE BROKER PRIORITY Priority2

    FOR CONVERSATION

    SET (CONTRACT_NAME = TestContract,

         LOCAL_SERVICE_NAME = TargetService2,

         REMOTE_SERVICE_NAME = N'InitService',

         PRIORITY_LEVEL = 10);

The following command initiates and sends a message on the conversation with a lower priority and then it repeat the same operations for the conversation with higher priority. Finally, we execute a read statement to receive the messages from the target queue.

DECLARE @dialog_handle UNIQUEIDENTIFIER ;

DECLARE @msg xml

set @msg= '<msg>msg1</msg>'

 

BEGIN DIALOG CONVERSATION @dialog_handle

   FROM SERVICE [InitService]

   TO SERVICE 'TargetService'

   ON CONTRACT [TestContract]

    WITH ENCRYPTION = OFF  ;

   

 SEND ON CONVERSATION @dialog_handle

    MESSAGE TYPE [RequestMsgType]

    (@msg) ;

 

set @msg= '<msg>msg2</msg>'

 

BEGIN DIALOG CONVERSATION @dialog_handle

   FROM SERVICE [InitService]

   TO SERVICE 'TargetService2'

   ON CONTRACT [TestContract]

    WITH ENCRYPTION = OFF  ;

   

 SEND ON CONVERSATION @dialog_handle

    MESSAGE TYPE [RequestMsgType]

    (@msg) ;

 

WAITFOR

(   

  RECEIVE cast(message_body as xml ) from ResponseQueue

)

If we use this application without SSB priorities the messages will be received from the ResponseQueue queue in the same order they were sent. However the use of priorities forces the SSB engine to reorganize the order in which messages are read. In the context of our sample, given that the second message is associated with a conversation with higher priority, the receive statement will produce the following output.

<msg>msg2</msg>

As you can see, the messages were received based on the conversation priorities level.

Although this is a very basic sample I hope it will give you an idea of the scenario on which we can apply conversation priorities on existing SSB applications.

No Comments