В этом случае
- HOLDLOCK = SERIALIZABLE = длительность, параллелизм
- TABLOCKX = эксклюзивная блокировка стола
Эти два понятия различны, и ни то, ни другое не соответствует вашему желанию.
Чтобы сделать то, что вы хотите, чтобы избежать условий гонки , вам необходимо принудительно установить неблокирующую (READPAST) монопольную (UPDLOCK) блокировку уровня строки (ROWLOCK). Вы также можете использовать предложение OUTPUT, чтобы сделать его единым оператором, который будет атомарным. Это хорошо масштабируется.
UPDATE
E
SET
[status] = 'PROCESSING', [username] = @Username
OUTPUT
INSERTED.*
FROM
(
SELECT TOP 1 id, [status], [username]
FROM Exceptions (ROWLOCK, READPAST, UPDLOCK)
WHERE [status] = 'READY'
ORDER BY id
) E
В общем, замки имеют 3 аспекта
- Гранулярность = что заблокировано = строка, страница, таблица (
PAGLOCK, ROWLOCK, TABLOCK
)
- Уровень изоляции = длительность блокировки, параллелизм (
HOLDLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE
)
- Режим = совместное использование / эксклюзивность (
UPDLOCK, XLOCK
)
И
- "комбинированный", например
NOLOCK, TABLOCKX