In working through some examples, sometimes I will see this pattern for receiving messages: What is the purpose of the "nested" WAITFOR (RECEIVE? What is this actually doing? Is it receiving the same message in both RECEIVE?
WAITFOR(
RECEIVE @dh = [conversation_handle],
@message_type = [message_type_name],
@message_body =CAST([message_body] ASNVARCHAR(4000))
FROM [Queue]), TIMEOUT 1000;
WHILE @dh ISNOTNULL
BEGIN
IF @message_type = N'http://schemas.microsoft.com/SQL/ServiceBroker/Error'
BEGIN
RAISERROR(N'Received error %s from service [Target]', 10, 1, @message_body)WITHLOG;
END
ENDCONVERSATION @dh;
COMMIT;
SELECT @dh =NULL;
BEGINTRANSACTION;
WAITFOR(
RECEIVE @dh = [conversation_handle],
@message_type = [message_type_name],
@message_body =CAST([message_body] ASNVARCHAR(4000))
FROM [Queue]), TIMEOUT 1000;
END
COMMIT;
Other times I will see this pattern for receiving messages: Why do a RECEIVE TOP(1) instead of just a RECEIVE?
WAITFOR
(RECEIVETOP(1)@conversationHandle =conversation_handle,
@messageTypeName = message_type_name,
@messageBody = message_body
FROM [Queue]),TIMEOUT 1000;
And other times I will see this pattern for receiving messages: What is the purpose of RECEIVING into an in-memory table when you can just process the message directly?
WAITFOR
(RECEIVE,conversation_handle,queuing_order
message_type_name
,message_body
FROM [Queue]INTO @tableMessages),TIMEOUT 1000;IF(@@ROWCOUNT= 0)BEGIN
COMMIT;BREAK;
END
What is the difference between the three approaches from an architectural and performance perspective? I need to process messages as fast as possible and I'm not sure why or when each should be used. Also, does the timeout have any impact on how FAST messages will be processed, or is it exactly what it says - a timeout - if a message is not found within the period then the procedure will break?