Хотя я не отвечаю прямо на ваш вопрос здесь, вместо того, чтобы заново изобретать колесо и усложнять себе жизнь, если вы, конечно, не наслаждаетесь им ;-), могу ли я предложить вам взглянуть на использование SQL Server Service Broker.
Предоставляет существующую платформу для использования очередей и т. Д.
Чтобы узнать больше, посетите.
Ссылка на брокера услуг
Теперь вернемся к вопросу, я не могу воспроизвести вашу проблему, так как вы увидите, что если вы выполните приведенный ниже код, данные будут возвращены независимо от порядка оператора select / update.
Итак, ваш пример выше.
create table #MSG_Q
(id int identity(1,1) primary key,status int)
insert into #MSG_Q select 0
DECLARE @queueid INT
BEGIN TRANSACTION TRAN1
SELECT TOP 1 @queueid = id FROM #MSG_Q WITH (updlock, readpast) WHERE #MSG_Q.status=0
UPDATE #MSG_Q SET status=1 WHERE id=@queueid
SELECT TOP 1 * FROM #MSG_Q WHERE #MSG_Q.id=@queueid
COMMIT TRANSACTION TRAN1
select * from #MSG_Q
drop table #MSG_Q
Возвращает результаты (1,1) и (1,1)
Теперь поменяйте местами порядок выписок.
create table #MSG_Q
(id int identity(1,1) primary key,status int)
insert into #MSG_Q select 0
DECLARE @queueid INT
BEGIN TRANSACTION TRAN1
SELECT TOP 1 @queueid = id FROM #MSG_Q WITH (updlock, readpast) WHERE #MSG_Q.status=0
SELECT TOP 1 * FROM #MSG_Q WHERE #MSG_Q.id=@queueid
UPDATE #MSG_Q SET status=1 WHERE id=@queueid
COMMIT TRANSACTION TRAN1
select * from #MSG_Q
drop table #MSG_Q
Результат: (1,0), (1,1) как ожидалось.
Возможно, вы могли бы еще более квалифицировать вашу проблему?