Handling Poison Messages Sample Code in BOL wrong?
In the "Example: Detecting a Poison Message" section, it reads:
This Transact-SQL example shows a simple, stateless service that includes logic for handling poison messages. Before the stored procedure receives a message, the procedure saves the transaction. When the procedure cannot process a message, the procedurerolls the transaction back to the save point. The partial rollback returns the message to the queue while continuing to hold a lock on the conversation group for the message.
BEGIN TRANSACTION ;
DECLARE @conversationHandle UNIQUEIDENTIFIER ;
DECLARE @messageBody VARBINARY(MAX) ;
DECLARE @messageTypeName NVARCHAR(256) ;
SAVE TRANSACTION UndoReceive ;
WAITFOR (
RECEIVE TOP(1)
@messageTypeName = message_type_name,
@messageBody = message_body,
@conversationHandle = conversation_handle
FROM ExpenseQueue
), TIMEOUT 500 ;
<error occurs -- rollback needed>
IF @@ERROR <> 0
BEGIN
ROLLBACK TRANSACTION UndoReceive ;
EXEC TrackMessage @conversationHandle ;
END ; <rest of example...>
After trying something similar, I believe that the "ROLLBACK TRANSACTION UndoReceive" statementreleases the lock on the conversation group. This means that the TrackMessage routine is not guaranteed exclusive access to the state data referenced by the @conversationHandle uniqueidentifier which could lead to data corruption.
To fix it, I think you need to have something like this:
begin tran; -- obtain an explicit lock on the conversation group -- handle possibly null @cgid here...
declare @cgid uniqueidentifier;
waitfor (
get conversation group @cgid from ExpenseQueue;
), timeout 500;
receive top(1) <error occurs -- rollback needed> <rest of example...>
@messageTypeName = message_type_name,
@messageBody = message_body,
@conversationHandle = conversation_handle
from ExpenseQueue
where conversation_group_id = @cgid;
begin
rollback transaction UndoReceive;
exec TrackMessage @conversation_handle;
end;
I would like some feedback on if my understanding is correct. I would like to avoid data corruption problems in our code.
Thanks -- Keith.

