Это похоже на ситуацию, в которой OUTPUT
может быть полезным:
-- Acknowledge and grab the next message
declare @message table (
-- ...your `ActionMessages` columns here...
)
update ActionMessages
set AcknowledgedTime = getdate()
output INSERTED.* into @message
where ActionMessageId in (select top(1) ActionMessageId from UnacknowledgedDemands)
and AcknowledgedTime is null
-- Use the data in @message, which will have zero or one rows assuming
-- `ActionMessageId` uniquely identifies a row (strongly implied in your question)
...
...
Там мы обновляем и извлекаем строку в той же операции, которая сообщает оптимизатору запросов точно , что мы делаем, позволяя ему выбрать наиболее детализированную блокировку и поддерживать ее для кратчайшего времени. возможное время (Хотя префикс столбца INSERTED
, OUTPUT
подобен триггерам, выражается через UPDATE
как удаление строки и вставка новой.)
Мне нужна дополнительная информация о ваших таблицах ActionMessages
и UnacknowledgedDemands
(views / TVFs / что угодно), не говоря уже о более глубоких знаниях автоматической блокировки SQL Server, чтобы сказать, необходимо ли это предложение and AcknowledgedTime is null
. Это необходимо для защиты от состояния гонки между дополнительным выбором и обновлением. Я уверен, что в этом не было бы необходимости, если бы мы выбирали из ActionMessages
(например, where AcknowledgedTime is null
с top
на update
вместо суб-выбора на UnacknowledgedDemands
). Я ожидаю, даже если это не нужно, это безвредно.
Обратите внимание, что OUTPUT
в SQL Server 2005 и выше. Это то, что вы сказали, что использовали, но если требуется совместимость с гериатрическими установками SQL Server 2000, вам нужно пойти другим путем.