Question

I'm noticing some conversations not getting closed, staying in CONVERSING state. The strange thing is, the queue is configured to process only 1 message at a time. In practice, however, there are 2 conversations in CONVERSING state, one which is really doing some work, and another one which seems to be stuck.

One thing I'm using is a single queue and service, which differs from the usual service broker implementations (making it more like a monologue instead of a dialog). I'm starting the activation SP with:

RECEIVE TOP(1)
    @Handle = conversation_handle,
    @MsgTypeName = message_type_name
FROM [//MyQueue]

IF (@@ROWCOUNT = 0)
    RETURN
ELSE IF ((@MsgTypeName is null) or (@Handle is null))
    RETURN
ELSE IF (@MsgTypeName != '//MyRequest')
    BEGIN
        END CONVERSATION @Handle
        RETURN
    END
Was it helpful?

Solution

Using "END CONVERSATION 'conversation handle' WITH CLEANUP;" is not wright way to end conversation.

Service broker is designed for dialogs, not monolog conversations. That should be also the reason why there is 2 conversations (one for sending service and the other for receiving service- as services can reside in different databases/instances)

You can create sending service, which is used for sending messages and receives "End Dialog" messages and ends dialog, the other which receives messages and does some processing with them + ends dialog when the work is done.

OTHER TIPS

Can you try

END CONVERSATION 'conversation handle' WITH CLEANUP;

I have worked with service broker in past. I would provide you some troubleshooting links I used to refer for service broker

http://www.mssqltips.com/tip.asp?tip=1197 http://blogs.msdn.com/b/sqlserverfaq/archive/2011/05/03/service-broker-concepts-and-troubleshooting.aspx

ssbdiagnose Utility - http://msdn.microsoft.com/en-us/library/bb934450.aspx

ELSE IF (@MsgTypeName != '//MyRequest')
    BEGIN
        END CONVERSATION @Handle
        RETURN
    END

Not a good idea. Try this:

IF @MsgTypeName = '//MyRequest'
BEGIN
  /* Do something here with the message */
END
ESLE IF @MsgTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
    END CONVERSATION @Handle
END
ELSE IF @MsgTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/Error'
BEGIN
     END CONVERSATION @Handle
    /* do some error reporting here */
END

Recall that BOTH the Initiator and the Target need to end the conversation before it can be truly ended. And that the Target is the one that typically sends the first END CONVERSATION message back to the Initiator. So now the Initiator (in code above) needs to inspect the incoming message type and act accordingly. If this is wrapped in a stored proc it will receive BOTH the actual reply message and the END CONVERSATION message, one right after the other.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top