Вы должны указать XLOCK-подсказку в своем выражении для достижения желаемого поведения.
Другая параллельная транзакция не может прочитать или записать выбранную строку.
SELECT *
FROM Employee e
WITH (XLOCK)
WHERE e.id = 123;
Теперь я хочу описать, почему HOLDLOCK и ROWLOCK не помогут.
HOLDLOCK
сообщит SqlServer о необходимости удерживать S-блокировки (общие блокировки) до завершения транзакции. S-блокировка предотвращает одновременную запись во время чтения. Но это позволяет читать данные одновременно. Вот почему это называется «общий». По умолчанию общие блокировки действуют так долго, как это предусмотрено текущим уровнем изоляции транзакции. Для уровня изоляции зафиксированного чтения (который используется по умолчанию) общая блокировка будет снята после того, как данные полностью прочитаны. Это означает, что блокировки на уровне строки снимаются сразу после чтения строки, блокировки на уровне страницы снимаются после того, как все данные на странице были прочитаны, а блокировки на уровне таблицы снимаются после завершения оператора. Но HOLDLOCK принудительно освобождает общие блокировки в конце транзакции. Таким образом, когда вы устанавливаете HOLDLOCK, общие блокировки оператора вынуждены жить дольше, как если бы они выполнялись в транзакции с повторяемым уровнем изоляции чтения.
XLOCK
работает так же, как HOLDLOCK, с одним отличием: X-блокировки (исключая используются блокировки.
UPDLOCK
вынуждает SqlServer использовать U-блокировки (обновления блокировок) вместо S-блокировок без каких-либо других отличий с подсказкой HOLDLOCK. U-блокировка - это определенный тип блокировки c для операторов чтения, за которыми следуют любые записи в транзакции, что потенциально может вызвать взаимоблокировки. Таким образом, вы используете UPDLOCK, когда хотите ограничить чтение одних и тех же данных во время одновременных транзакций с целью обновления.
ROWLOCK
говорит SqlServer держать блокировки на уровне строки, даже если предполагается блокировка на уровне страницы или таблицы использоваться. По сути, вам не нужно указывать ROWLOCK, если вы не уверены, что делаете, потому что вы можете усложнить выполнение операторов.