Matthew Roberts (mroberts_hm@hotmail.com) writes:
[quoted text, click to view] > In requesting the next work item, I use the following SQL syntax:
>
> DECLARE @workitem varchar(512)
> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
> BEGIN TRANSACTION
> SELECT TOP 1 @workitem=WorkItemName FROM WorkItems WHERE Status=1
> ORDER BY DateSubmitted
> UPDATE WorkItems SET Status=2 WHERE WorkItemName=@workitem
> SELECT * FROM WorkItems WHERE WorkItemName=@workitem
> COMMIT TRANSACTION
>
> The idea is that the Transaction Isolation Level, along with the three
> statements in the transaction block, will only let one thread at a
> time request the next work item. The three statements in the
> transaction block select the next work item, mark it as in process,
> then return the work item to the calling thread. In limited testing,
> all seems well. Before going into production, however, I would like to
> see if anyone can confirm that my ideas will indeed prevent threads
> from duplicating each other's work.
I think you need to add locking hint to the first SELECT statement:
SELECT TOP 1 @workitem=WorkItemName
FROM WorkItems WITH (UPDLOCK) WHERE Status=1
ORDER BY DateSubmitted
Else two processes can read the same @workitem value, and proceed to
the update statement, and both will wait for each other, until the
deadlock detection mechanism rolls one of them back.
The UPDLOCK changes that, because only one process at a time can have
an UPDLOCK at a row. (But the lock does not block readers that only
requires shared locks.)
There is anothing here which makes me a little nervous. Is WorkItemName
unique in this table? Since it's a varchar(512) it does not look like
a typical primary key. If there could be more than one row with the
same work-item name theoretically, process A and process B could
read the same @workitemname from two different rows. Since the rows
would be different, they would not block each other.
Even if WorkItemName is unique, I would recommend you to put this in
the ORDER BY clause to make it completely deterministic in any given
situation which row you get.
--
Erland Sommarskog, SQL Server MVP, sommar@algonet.se
Books Online for SQL Server SP3 at