I am implementing a message queue system in SQL Server 2000. My queue table looks something like this:
[MessageId] [uniqueidentifier] NOT NULL,
[MessageType] [uniqueidentifier] NOT NULL,
[Status] [tinyint] NOT NULL,
[SubmittedTime] [datetime] NOT NULL,
[StartTime] [datetime] NOT NULL,
[DispatchedTime] [datetime] NULL,
[CompletedTime] [datetime] NULL,
[MessageData] [image] NULL
This is how I retrieve the next message for processing:
SELECT TOP 1 *
FROM [Queue].[MessageQueue] WITH (ROWLOCK, UPDLOCK, READPAST)
WHERE [StartTime]=@pStartTime AND [MessageType]=@pMessageType AND [Status]=@pStatus
ORDER BY [StartTime]
and mark it as being processed:
UPDATE [Queue].[MessageQueue] SET [Status]=1 WHERE [MessageId]=@pMessageId
After message has been processed I delete it from the queue:
DELETE FROM [Queue].[MessageQueue] WHERE [MessageId]=@pMessageId
All database accesses are transactional with default READ COMMITTED. The problems start when there are a few concurrent accesses: I get deadlocks when retrieving next message. If I do not delete message after processing then there is no deadlock. But this is not what I need.
I played with different isolation levels and locking hints and was able to avoid deadlock using TABLOCKX:
SELECT .... FROM [Queue].[MessageQueue] WITH (TABLOCKX)
But in this case you cannot concurrently retrieve messages which was my goal from the beginning. How do I achieve this
Thank you,
Alex

Implementing message queue in SQL Server 2000
Francisco Lopez
I thought about Service Broker. What implications can I run into Performance, scalability How hard is it to learn and implement
Alex
JohnReam
--
Adam Machanic
Pro SQL Server 2005, available now
http://www..apress.com/book/bookDisplay.html bID=457
--
BamaGal
I just tested the same code with SQL Server 2005 and there was no deadlocks! Can someone confirm/explain this
Alex
apander
Scalability could be better, but performance is definitely not. I just ran some tests - Service Broker vs. my queue implementation: on 10000 messages Service Broker took 8min 13sec, my queue - 6min 51sec.
A couple more questions:
1. How do I set message priority
2. If the service is defined with multiple contracts is there a way to receive a message with a specific contract
Alex
Metaxa777
The documentation says:
"The WHERE clause of the RECEIVE statement may only contain search conditions that use conversation_handle or conversation_group_id."
Looks like 2 is impossible unless I am missing something.
Alex
Nik02
--
Adam Machanic
Pro SQL Server 2005, available now
http://www..apress.com/book/bookDisplay.html bID=457
--
Millen Tomov
What happens if message processing fails in the middle (for instance, app server goes down) The message is lost.
Any other ways
Alex
Mosha Pasumansky
--
Adam Machanic
Pro SQL Server 2005, available now
http://www..apress.com/book/bookDisplay.html bID=457
--
GrandmaGG
--
Adam Machanic
Pro SQL Server 2005, available now
http://www..apress.com/book/bookDisplay.html bID=457
--
hoogli
--
Adam Machanic
Pro SQL Server 2005, available now
http://www..apress.com/book/bookDisplay.html bID=457
--
Damodar
1. I have an index on [StartTime].
2. I was experimenting with different locks: ROW, PAGE etc.
3. I use UPDLOCK so the same message will not be retrieved more than once for processing.
4. Snapshot isolation level is not available in SQL 2000.
5. Workload - 5000+ messages in the queue.
Alex
iowaporter
Alex I have some questions.
Do you have any indexes defined on your table
Why do you use ROWLOCK
Why do you use UPDLOCK
Is Snapshot Isolation disbled on SQL 2005 on which you have tried this
And could you also describe your workload
Vincent Rainardi
--
Adam Machanic
Pro SQL Server 2005, available now
http://www..apress.com/book/bookDisplay.html bID=457
--
Event666