I'm new to Service Broker. We've set up a development system that appears to be working well.
One strange thing I've noticed is that the conversation handles in the audit tables at each end of the Service Broker are different for the same message. I had assumed the same conversation handle would be used by the initiator and target ends so I'm wondering if we've got something configured wrong.
Is it normal for a single message to have different conversation handles at each end of a conversation?
There is a conversation_id
, which is the same at both endpoints.
And there is conversation_handle
, which must be different at each endpoint. Think at the very simply scenario when the initiator and target are in the same database. Had the conversation_handle
be the same then it would be ambiguous which endpoint you mean when you issue a SEND
. Did you send from initiator to target, or from target to initiator? If the handle is the same, can't distinguish! Therefore the handle must be different.
You always interact in your application with conversation_handle
. This is the value you pass to your T-SQL statements (SEND
, END
, MOVE
), and this is what BEGIN DIALOG
returns. The handle value never leaves the box (is not part of the message wire format).
You use the conversation_id
mostly in debugging. It can be used to identify your peer converstaion endpoint on a remote machine, it can be used to identify the conversation in message related events in SQL Profiler (Broker Event Category).
After you get past this A-ha moment, soon you'll be confused by the fact that conversation_group
is always local and does not travel on the wire. It was asked before here, read 1314050 or 6434464.
And there is one more id: the message_id
. This is assigned to the message during SEND
. It travels on the wire, and is use is only for debugging and troubleshooting. Eg. it features in Broker:Forwarded Message Dropped Event Class.
I've been looking for definitive information about this on the web. Here's what I found:
Conversation handles are definitely different at each end of a conversation. They uniquely identify the endpoint of the conversation, not the conversation as a whole. The conversation_id is the conversation identifier that is shared by both ends of the conversation.
Here's the Books Online entry for sys.conversation_endpoints. It says:
conversation_handle: Identifier for this conversation endpoint. (emphasis mine)
conversation_id: Identifier for the conversation. This identifier is shared by both participants in the conversation. (emphasis mine)
In addition, Microsoft has a PDF online with a sample chapter of the book The Rational Guide To SQL Server 2005 Service Broker, written by the program manager for Service Broker, Roger Wolter. For those with access to the book this is chapter 2, Conversations. The section Conversation Persistence has this explanation of conversation_ids and why conversation handles have to be different at each end of the conversation:
conversation_id — This is the "on the wire" identifier for a conversation. This identifier is included in each message sent across the network. Each message of this conversation has this uniqueidentifier in its header so that the endpoint knows which conversation the message belongs to. At this point, you are probably wondering when to use the conversation_handle instead of another uniqueidentifier. When both endpoints of a conversation are in the same database (as they were in the ISBN Lookup example in Chapter 1), there will be two rows in the table for the same conversation. Therefore, we need two handles as keys.
This puzzled me when I first started using service broker but you're not seeing things - the id's are different at each end.
I gave this quite a lot of thought (couldn't find any definitive documentation on it) and came up with the following reasoning. The conversation Id is really a correlation identifier that logically groups messages inside a service boundary, i.e. on either the sender or the receiving end, so there is no compelling reason why the ID has to be the same on both sides (even if that would be convenient for debugging).
If there is no good reason why they should be the same then it makes sense for them not to be the same. There is a tiny, tiny chance that you could get a GUID collision if you used one on a machine that didn't create it, so I guess they decided it would be better to generate a new one.
[Happy to be corrected by anyone who knows more about this....]
来源:https://stackoverflow.com/questions/19415724/should-conversation-handles-be-the-same-at-each-end-of-a-service-broker