Как заблокировать строку, которая предотвращает работу CRUD

Привет, эксперт как я могу заблокировать строку на сервере sql, которая предотвращает работу CRUD даже с SELECT. Является ли это возможным? Сериализуемый уровень изоляции не мешает SELECT. спасибо

Ответ 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), который обеспечит грязное чтение.