In SQL Server a dialog involves EXACTLY two parties...one called the Initiator and the other called the Target. At a bare minimum the conversation goes like this:
In my post on CLOSED conversations I discussed why it is so important that the target always ends the conversation first. If you don't remember this then you probably have modeled the fire-and-forget pattern which is dangerous. I covered fire-and-forget in my last post.
But my experience is that many (most) SSB implementations really should be simple f&f patterns. In fact, this is the most common messaging pattern for other messaging technologies like MSMQ, RabbitMQ, and JMS, to name but a few. The most common use case I've seen for SSB is where you need to send a message to another SSB service to initiate some asynchronous processing after a certain data event occurs. For instance, a trigger sees a data change which pushes a message onto a queue to launch an ETL process. The initiator (the trigger) couldn't care less when the ETL process completes, or even if completes without error...that is some other process' job to monitor that.
What I just described is a monolog. A one-way conversation. A one-sided dialog. That's f&f. That's not modelable out-of-the-box with SSB. But it's quite easy to do. Again, it's the default for every other messaging technology that I know of.
You can model monologs in Service Broker just like in other messaging systems, but you can't do it with "fire and forget"...or at least you shouldn't. For a monolog in SSB you really need to have an activator on the initiator side that is ENDing CONVERSATION. But remember, this must be done after the target does its processing and does an END CONVERSATION first. The target always ends the conversation first. That is the key to a safe monolog.
Let's look at the use case where "I need to start a stored procedure asynchronously from a trigger." Invariably a google search will yield that some folks model this by launching SQL Agent jobs. This is true f&f. It works great. But it's not very elegant IMHO. Why?
So, further down in the google search results someone will suggest Service Broker. This is much more elegant. But it is a bit confusing for SSB noobs. Here's why:
Here is how I always model a monolog. If you follow this pattern it will always work. Safely. Download the code if you want to follow along. First, we need two queues and two services. To properly model a monolog you still need two of each of these objects. The "sender" really does nothing important in the monolog, it's simply there because there is no other way to do monologs properly.
The SenderQ
, while not functionally important, does serve a purpose...it must "acknowledge" the receipt of the message from the ReceiverQ
. So let's create a very rudimentary activator proc whose sole purpose is to acknowledge the receipt of the processed message from the ReceiverQ
. All this proc really needs to do is END CONVERSATION
on the sending side.
Once the activator proc is created we "attach" it to the SenderQ
. For purposes of the demo we'll temporarily disable activation.
With everything set up let's see this in action. Let's say you have a long-running process that you want to launch asynchronously and in an autonomous transaction. The code below will do this. We simply need to enqueue a message from the SenderSvc to the ReceiverSvc
. This can be from our Java app, a stored procedure, or even a trigger.
The "message payload" is whatever work we want to do. Note that we NEVER END CONVERSATION
from the sender first. The target needs to be the first to END CONVERSATION, otherwise you risk fire-and-forget problems.
Let's check what happened:
The message was successfully enqueued to the ReceiverQ
and is waiting to be processed. Normally if we had the activator proc enabled it would immediately pick up the message and process it. But we have that disabled for this demo. Let's look at how the ReceiverQ
would process the message:
Line 95 is where we would do whatever asynchronous work is required. Note that we are following our rule that we always END CONVERSATION
on the receiver-side first.
After "processing" we query the queues and note that the message was removed from the ReceiverQ
and a new message of type EndDialog
was placed back into the SenderQ
.
This the weird anamoly with Service Broker "monologs"...the SenderQ
must process that acknowledgement. This is where a SSB monolog is really a dialogue. No other messaging frameworks work this way. This is where the activator comes into play. We left the SenderQ's activator disabled so we could see the EndDialog
sit in the queue. Let's enable the activator and see what happens:
Here we have enabled the activator and we see that the EndDialog
was automatically processed.
Summary
The most common messaging pattern is the fire-and-forget pattern, also called a monolog. Unfortunately SSB doesn't natively support monologs. The correct pattern is akin to a "one-way dialog". We simply attach an activator proc to the sending queue. It's sole responsibility is to acknowledge that the target service has processed the message. Armed with this information you can now safely model monolog patterns in Service Broker.
You have just read "Service Broker Demystified - Can I model monologs? Yes you can!" on davewentzel.com. If you found this useful please feel free to subscribe to the RSS feed.
Dave Wentzel CONTENT
sql server service broker service broker demystified