Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
DB Engine
SQL ServerMSDESQL Server CE
Services
Analysis (Data Mining)Analysis (OLAP)DTSIntegration ServicesNotification ServicesReporting Services
Programming
CLRConnectivitySQLXML
Other Technologies
ClusteringEnglish QueryFull-Text SearchReplicationService Broker
General
Data WarehousingPerformanceSecuritySetupSQL Server ToolsOther SQL Server Topics
DirectoryUser Groups
Related Topics
MS AccessOther DB ProductsMS Server Products.NET DevelopmentVB DevelopmentJava DevelopmentMore Topics ...

SQL Server Forum / Other Technologies / Service Broker / February 2008

Tip: Looking for answers? Try searching our database.

Disabled Queue

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
John Cantley - 30 Jan 2008 22:17 GMT
Ok, I am getting a disabled queue as a result of message poisoning, i guess.
The question is.
The correct steps to enable are
   remove the suspect conversations from the transmission queue
   Alter the queue Status=ON

Is this correct?

John
Craig Thomas - 30 Jan 2008 23:45 GMT
John,

You're exactly right about the remedy.

The cool thing, though, would be to avoid allowing the poison message to
disable the queue. Then you wouldn't have to intervene with a manual
procedure.

There's a good writeup in books online that describes a way to keep poison
messages from tripping the off switch.
http://msdn2.microsoft.com/en-us/library/ms171592.aspx

Also, you can monitor for "Broker:Queue Disabled" events using SQL Server
Agent. Then you can get notified by the software -- instead of by an unhappy
customer.

Hope that helps.

Thanks,
--Craig.

> Ok, I am getting a disabled queue as a result of message poisoning, i guess.
> The question is.
[quoted text clipped - 5 lines]
>
> John
Craig Thomas - 31 Jan 2008 00:05 GMT
John,

Forgot to mention this reference about manually removing poison messages:
http://msdn2.microsoft.com/en-us/library/ms166137.aspx

Thanks,
--Craig.

> John,
>
[quoted text clipped - 26 lines]
> >
> > John
John Cantley - 31 Jan 2008 17:37 GMT
Thanks Craig,

  I think my problems were stemming from a WaitFor in the activation proc.
Since it is activation then I think a waitfor is not called for and I just
need to do a Receive Top(1), which leads to another question. I have only
one listener on the queue and would prefer to leave it that way. A response
from the target back to the generates two messages on the queue, the actual
response and the EndDialog. Do I end the conversation during the response
processing or do I just let the next message (EndDialog) end that
conversation?

> John,
>
[quoted text clipped - 37 lines]
>> >
>> > John
Craig Thomas - 04 Feb 2008 22:43 GMT
Hi John,

You may be well past this by now. But on the off-chance...

There are a good many patterns that your activated stored
procedure can implement to process the messages on its
queue.

What happens under the covers can be revealed by using SQL
Profiler.

When this statement:
 CREATE QUEUE [RequestQueue]
     WITH STATUS = ON,
     ACTIVATION (
         STATUS = ON,
         PROCEDURE_NAME = [ProcessRequests],
         MAX_QUEUE_READERS = 1,
         EXECUTE AS SELF
     );

is executed, or later when an ALTER QUEUE statement re-
enables the queue with activation, Service Broker creates a
thread that starts the stored procedure.

One pattern that works involves no WAITFOR statement. This
works great if there is a message waiting in the queue. The
RECEIVE TOP(1) statement retrieves the message immediately,
processes it, and the stored procedure exits. When the next
message is written to the queue, Service Broker activates
the procedure, it retrieves the message, processes it,
exits, and so on. If your application messaging model
includes not too many messages, this simple approach may be
okay.

There is a cost associated with activation. Another pattern
involves using a WHILE loop and a WAITFOR. In this pattern,
the activated stored procedure runs continuously as long as
there are messages waiting to be read from the queue. If it
finds that the queue is empty, it will wait for a while (an
interval worth tuning), to see if a message shows up. If it
does receive a message within the WAITFOR timeout, it will
process it, and continue the loop. If the timeout expires
before a new message arrives, the loop exits, and the stored
procedure exits. When a new message is delivered, Service
Broker activates the stored procedure, and the process of
looping and waiting begins again. If your application
messaging model includes multiple message conversations, or
a fairly spiky message load, this approach is pretty
efficient.

Other patterns serve application messaging models in which
there are bursts of messages, continuous high volume, or
scenarios in which queues are disabled during the day and
processing has to catch up during the night.

There is no one-size-fits-all pattern.

However, it is important to handle errors. And error
handling can make a simple pattern look a bit raggedy.

Here is the pattern I have found to work well in the
application I am building:

-----

CREATE PROCEDURE ProcessRequests
AS
 DECLARE @lclConversationHandle UNIQUEIDENTIFIER
 DECLARE @lclMessageTypeName NVARCHAR(256);
 DECLARE  @lclMessageBody XML;
 DECLARE @lclResponseMessage XML;

 WHILE (1=1)                 -- Loop as long as there are messages in the
queue
 BEGIN

     BEGIN TRANSACTION       -- Interact with the queue transactionally

     WAITFOR (
       RECEIVE TOP(1)        -- Receive messages from queue one at a time.
         @lclConversationHandle = conversation_handle,
         @lclMessageTypeName = message_type_name,
         @lclMessageBody = CAST(message_body AS XML)
       FROM TargetQueue
     ), TIMEOUT 60000;       -- Don't wait forever. After a minute, stop
waiting

     IF (@@ROWCOUNT = 0)     -- This condition results from a timeout
(generally)
     BEGIN                   -- We have exited the waitfor and have no
messages.
       ROLLBACK TRANSACTION; -- Rollback (nothing ventured, nothing gained).
       BREAK;                -- Break out of the while (1=1) loop. Service
Broker
     END                     -- will activate this stored procedure again
when
                             -- messages are delivered to its queue.

     SAVE TRANSACTION MessageReceived; -- This save point lets the procedure
                             -- rollback everything *except* the receive
from the
                             -- queue, should an unrecoverable error occur
in processing
                             -- the message.

     IF (@lclMessageTypeName = 'http://www.bar.foo.com/RequestMessage')
     BEGIN                   -- Attempt to handle this message.

       BEGIN TRY             -- Do whatever processing is required
                             -- knowing that if an error occurs, the catch
block below
                             -- will get control.
         -- ... process the request ...
         -- Construct the response message
         -- ... prepare response ...
         -- Send the response
         SEND ON CONVERSATION @lclConversationHandle
           MESSAGE TYPE [http://www.bar.foo.com/ResponseMessage]
             (@lclResponseMessage);

         -- End the conversation
         END CONVERSATION @lclConversationHandle;

       END TRY

       BEGIN CATCH           -- Determine if the error is recoverable
         IF (ERROR_NUMBER() = 1205)  -- Deadlock error. This is
recoverable, so
         BEGIN
           ROLLBACK TRANSACTION;     -- Rollback the whole transaction,
including the
           CONTINUE;                 -- read from the queue, and continue
the while loop
         END
         ELSE                -- A non recoverable error occurred. To avoid
poisoning the
         BEGIN               -- queue, rollback to the save point after the
queue was
                             -- read (so the unprocessable message is not
re-read).
           ROLLBACK TRANSACTION MessageReceived;
           -- Any other error logging as appropriate ...
         END
       END TRY
     END

     IF (@lclMessageTypeName =
'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
     BEGIN
       -- End the conversation
       END CONVERSATION @lclConversationHandle;
     END

     COMMIT TRANSACTION;     -- Commit either (1) everything, including the
queue
                             -- receive and whatever message processing
work was done,
                             -- or (2) just the queue receive after the
catch block
                             -- rolled back a non recoverable error to the
save point
                             -- at MessageReceived
 END -- WHILE (1=1)

GO

-----

Hope that is useful.

Thanks,
--Craig.

> Thanks Craig,
>
[quoted text clipped - 48 lines]
> >> >
> >> > John
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.