Привет, эксперт как я могу заблокировать строку на сервере sql, которая предотвращает работу CRUD даже с SELECT. Является ли это возможным? Сериализуемый уровень изоляции не мешает SELECT. спасибо
Как заблокировать строку, которая предотвращает работу CRUD
Ответ 1
BEGIN TRAN
SELECT 1
FROM Table
WITH (XLOCK, ROWLOCK)
COMMIT TRAN
Это сделает трюк.
ИЗМЕНИТЬ
Как уже отмечалось другими, вы не можете заблокировать строку, которую нельзя прочитать. Единственный способ, которым я это знаю, заключается в следующем:
WITH (UPDLOCK, TABLOCK)
И это предполагает, что WITH (NOLOCK) никогда не используется в инструкции SELECT (чего следует избегать в любом случае).
Я тестировал это, и он будет работать, хотя TABLOCK следует использовать только в крайних случаях. Конечно, если требуется concurrency, это будет плохое решение, и потребуется какая-то другая форма блокировки. Один из способов - обновить бит столбца "Доступный True/False" и только прочитать строки, где Available = True. Как предположил @gbn, с этим можно было бы использовать READPAST.
Ответ 2
попробуйте использовать ROWLOCK
и UPDLOCK
внутри транзакции примерно так:
BEGIN TRANSACTION
SELECT @ID = ID
FROM YourTable WITH (ROWLOCK, UPDLOCK)
WHERE ....
--more--
COMMIT TRANSACTION
однако вы не можете помешать SELECT, который использует подсказку NOLOCK с "грязного" чтения этого.
Ответ 3
SQL Server уже изначально блокирует запись из грязных чтений по мере ее обновления. Это приводит к блокировке вызова выбора до тех пор, пока вызов обновления/вставки не будет завершен.
Ответ 4
Как и ROWLOCK, XLOCK, как было предложено другими людьми, я бы подумал о READPAST
Это позволяет другим читателям и писателям пропускать блокировку в этой строке. Это может увеличить concurrency, потому что блокировка, установленная ROWLOCK, блокировка XLOCK s в противном случае
Ответ 5
Можно заблокировать строку с помощью сочетания WITH (ROWLOCK), но оператор SELECT всегда может обойти его, добавив блокирующий подсказку WITH (NOLOCK), который обеспечит грязное чтение.