Thursday, February 23, 2006

SQL Server Service Broker Newbie Problems - Part II

So after figuring out my last problem, I was still unable to do something as simple as send a test message from one simple service to another. Here's how I was setting things up:

 


create queue mysenderqueue with status = ON;

create queue myreceiverqueue with status = ON;

create service mysenderservice on queue mysenderqueue;

create service myreceiverservice on queue myreceiverqueue;

 

declare @dialog_handle uniqueidentifier

begin dialog conversation @dialog_handle from service mysenderservice to service 'myreceiverservice';

send on conversation @dialog_handle ('This is a message');

 

Those of you that know Service Broker will already have spotted the problem. It took me a little longer. :P

 

The symptoms here are what were so confusing to me. After running the above SQL, if I did a

 


select * from mysenderqueue;

select * from myreceiverqueue;

 

I'd see that there were no messages in receiverqueue, but senderqueue had one. WTF? Why didn't my message go to the right queue?

 

With the help of the inestimable Bob Beauchemin, I was able to figure out that what I should have been doing was this instead:

 


select cast(message_body as XML) from mysenderqueue;

 

If I had, I would have seen that the message in senderqueue actually said

 

<Error xmlns="http://schemas.microsoft.com/SQL/ServiceBroker/Error">

  <Code>-8425</Code>

  <Description>The service contract 'DEFAULT' is not found.</Description>

</Error>

 

So really, it wasn't that my message was going to the wrong queue, it was that Service Broker was bouncing my message and queuing an error back to the originating service.

 

Now, I was still confused, because this seems to imply that the DEFAULT contract isn't defined, when I can clearly see that it is via SQL Server Management Studio. A bit more digging revealed the following line in the docs for CREATE SERVICE:

 

"If no contracts are specified, the service may only initiate conversations."

 

While surprising (why name a contract DEFAULT if it's not the default?) this certainly was consistent with what I was seeing. Once I changed my service definition for the receiver service to be

 


create service myreceiverservice on queue myreceiverqueue ( [DEFAULT] );

 

then everything started working. Cool! Now on to the next newbie problem!

1 comment: