Какой эффект HOLDLOCK имеет на UPDLOCK?

Создайте proc/view в своей базе данных.

30
задан Stevoisiak supports Monica 22 January 2018 в 18:18
поделиться

1 ответ

Это имеет большое влияние.

Блокировка обновления принимает блокировку обновления строки, обновление намерения на странице и общее блокировка таблицы / базы данных.

Это не останавливает другие запросы от доступа к данным в таблице, поскольку блокировки на странице / базе данных являются чисто долевыми блокировками. Они просто не могут столкнуться с блокировками отдельной строки / страницы / таблицы, пытаясь выполнить операцию, которая противоречила бы блокировкам. Если это произойдет, запрос будет стоять в очереди за текущими блокировками и будет ждать, пока он станет доступным, прежде чем он сможет продолжить.

При использовании блокировки запрос принудительно сериализуется, блокируя таблицу исключительно до завершения действия. Это предотвращает чтение таблицы кем-либо, если не используется подсказка nolock, что допускает потенциально грязное чтение.

Чтобы увидеть эффект, сгенерируйте пример таблицы 'foo' и поместите в нее несколько мусорных данных.

begin tran

select * from foo with (updlock)
where tableid = 1
-- notice there is no commit tran

Откройте другое окно и try:

select * from foo

Строки возвращаются, теперь фиксируется исходная транзакция запроса. Запустите его повторно, чтобы также использовать блокировку:

begin tran

select * from foo with (updlock, holdlock)
where tableid = 1

Вернитесь в другое окно и попробуйте снова выбрать данные, запрос не вернет значения, так как он заблокирован эксклюзивной блокировкой. Зафиксируйте транзакцию в первом окне, и результаты второго запроса появятся, так как он больше не заблокирован.

Заключительный тест - использовать nolock, запустить транзакцию еще раз с помощью Updlock и holdlock. затем запустите следующее во втором окне:

select * from foo (nolock)

Результаты вернутся автоматически, так как вы приняли на себя риск «грязного» чтения (чтение незафиксировано).

Таким образом, видно, что оно имеет большое влияние, поскольку вы вынуждают сериализовать действия против этой таблицы, что может быть тем, что вы хотите (в зависимости от выполняемого обновления), или создаст очень большое узкое место в этой таблице. Если бы все сделали это с занятой таблицей с длительными транзакциями, это вызвало бы значительные задержки в приложении.

Как и все функции SQL, при правильном использовании они могут быть мощными, но неправильное использование функции / подсказки может вызвать серьезные проблемы. Я предпочитаю использовать подсказки как последнее средство, когда мне нужно переопределить движок, а не как подход по умолчанию.

Редактировать как запрошено: протестировано в SQL 2005, 2008, 2008R2 (All Enterprise) - все установлено практически по умолчанию настройки, тестовая база данных создана с использованием всех значений по умолчанию (только что введено имя БД).

63
ответ дан 27 November 2019 в 23:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: