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. Fire-and-forget (f&f) is where the initiator sends a message and immediately ends the conversation because it doesn't need or care for the target acknowledging its receipt of the message.
But my experience is that many (most) SSB implementations really should be simple f&f patterns. 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 an 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.
What's wrong with fire-and-forget? You risk lots of side-effects like
END CONVERSATION WITH CLEANUP;)
END CONVERSATION WITH CLEANUP;.
Let's demo that.
Fire-and-forget at it's worst
If you want to follow along you can download the demo script here.
We'll start by creating the most basic send and receive queue.
Next we'll send a message and immediately
END CONVERSATION (Line 33). This is the f&f anti-pattern.
Note that we have no errors and we have two messages in the
ReceiverQ. They both have the same conversation_handle. The first message is the actual message and the second message is the
EndDialog, corresponding ot the
Next we want the receiver to process the message(s)...
...and note the messages are processed without any error...
So far so good. There's no problem with f&f that I can see.
But now let's assume that something "changed" on the receiver service. Perhaps it begins throwing errors due to a logic bug in your activator code...perhaps there is a disk space issue...or perhaps someone decided to attach a contract to the receiver. Let's look at what happens. Here we create a simple constraint that messages much be well-formed XML. Of course or original message was NOT XML, so it should now fail.
Let's start over and see what happens. We'll build another f&f message that is NOT XML and send it.
No errors so far and we again see the same two messages in the
ReceiverQ. So far nothing has changed.
Ah, now let's see what happens when the receiver tries to process the message. Remember, it should throw some kind of error about the message not being valid XML.
Nope, all Queues are clean!
Your initial reaction may be that our messagetype/contract is not working. They are.
Let's think about what happened. When we sent the message we immediately did
END CONVERSATION meaning that the sending service does not care to see ANY messages, even failures. The error is lost forever. You may be thinking that the error should maybe be retained SOMEWHERE...like sys.transmission_queue maybe. You'd be wrong. That queue is solely to retain messages that failed due to communication problems. Our failure was due to a contract problem .
This is why fire-and-forget is so dangerous. You'll likely never see the side effects of f&f until you accidentally change something in your prod system. And then determining that you've just been bitten by f&f is not easy because no error logging is maintained.
Lots of people try to model a fire-and-forget pattern because the need for this use case is so prevalent. Don't do that. Simply remember that the target always ends the conversation first. If you remember that then you won't end up with lost errors like the above demo. In the next post I'll cover how to safely monitor a monolog, which is the use case that most people need and is often confused with fire-and-forget.
You have just read "Service Broker Demystified - Fire and Forget Anti-Pattern" 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