Я использую подсказки sql UPDLOCK и READPAST в хранимой процедуре, чтобы реализовать сортировку очереди таблицы (я говорю сортировку, потому что выбираю топ 1500 вместо топ 1 и не удаляюстрок после того, как я их выбрал. Подробнее см. вопрос Возврат разблокированных строк в запросе "select top n" ).
Я провел несколько тестов с простой маленькой таблицей, и все кажетсячтобы работать отлично - второй вызов SP не ждет окончания первого вызова, просто пропускает строки, заблокированные первым вызовом, и возвращает следующие.На моем реальном столе, хотя, это работает только иногда ... в других случаях второй вызов зависает и ждет завершения первого.Это связано с тем, что первый вызов блокирует всю таблицу, а не только некоторые строки.
Это SP для тестовой таблицы и реальной таблицы:
Реальная таблица:
declare @temp as table (ID int primary key, timestamp datetime)
BEGIN TRANSACTION
insert into @temp
SELECT TOP 1 ID, getdate()
FROM subscription WITH (UPDLOCK, READPAST)
WHERE IsBeingProcessed = 0
waitfor delay '00:00:10'
UPDATE subscription
SET IsBeingProcessed = 1
from subscription
inner join @temp t on subscription.id = t.id
COMMIT TRANSACTION
select * from @temp t
inner join subscription s on s.id = t.id
Тестовая таблица:
declare @temp as table (ID int primary key)
BEGIN TRANSACTION
insert into @temp(id)
select top 1 id
from test WITH (UPDLOCK, READPAST)
where msg like 'test'
waitfor delay '00:00:10'
UPDATE test
SET timestamp = getdate()
from test
inner join @temp t1 on test.id = t1.id
COMMIT TRANSACTION
select * from test t
inner join @temp t1 on t.id = t1.id
Запуск sp_lock Я вижу, что первая SP на всей моей "реальной" таблице удерживает монопольную блокировку таблицы, в то время как вторая SP ожидает намеренную монопольную блокировку.Для моей «тестовой» таблицы у меня есть блокировка обновления для индекса и идентификатора строки, две намеренные блокировки обновления на двух страницах и целенаправленная эксклюзивная блокировка для всей таблицы.
Есть ли какая-либо идея, которая могла бы вызвать блокировку всей таблицы "реальной таблицы"?
Может быть, некоторые кластерные индексы, которые у меня есть в этой таблице, может быть, некоторые индексы, которые я пропускаю?Я не знаю.
Пример, который я разместил, очень прост - у него есть "top 1" и нет "order by".Мой реальный выбор будет иметь «порядок по идентификатору» и «топ 1500», возможно, «топ 3000».Это может сделать проблему блокировки еще хуже.
Любая идея очень приветствуется!Спасибо.