Ответ 1
Это оказывает большое влияние.
Блокировка обновления блокирует обновление в строке, обновление Intent на странице и общую блокировку в таблице/базе данных.
Это не останавливает другие запросы от доступа к данным в таблице, поскольку блокировки на странице/базе данных являются чисто блокировками общего доступа. Они просто не могут блокировать блокировки против отдельной строки/страницы/таблицы, пытаясь выполнить операцию, которая противоречит блокировкам. Если это произойдет, запрос будет стоять в очереди за текущими замками и ждать, пока он появится, прежде чем он сможет продолжить.
Используя holdlock, запрос принудительно сериализуется, блокируя таблицу только до завершения действия. Это препятствует тому, чтобы кто-нибудь читал таблицу, если не используется подсказка nolock, позволяющая читать потенциально грязную информацию.
Чтобы увидеть эффект, сгенерируйте примерную таблицу "foo" и поместите в нее некоторые данные мусора.
begin tran
select * from foo with (updlock)
where tableid = 1
-- notice there is no commit tran
Откройте другое окно и попробуйте:
select * from foo
Строки возвращаются, теперь фиксируют транзакцию исходного запроса. Повторно запустите его, чтобы использовать holdlock:
begin tran
select * from foo with (updlock, holdlock)
where tableid = 1
Вернитесь в другое окно и попробуйте снова выбрать данные, запрос не будет возвращать значения, поскольку он блокируется исключительной блокировкой. Перенесите транзакцию в первом окне, и результаты во втором запросе появятся, так как она больше не заблокирована.
Окончательный тест заключается в использовании nolock, повторите транзакцию с помощью updlock и holdlock. затем запустите следующее во втором окне:
select * from foo (nolock)
Результаты будут возвращаться автоматически, так как вы приняли риск грязного чтения (читайте без фиксации).
Таким образом, это, как видно, оказывает большое влияние на то, что вы вынуждаете действия против этой таблицы быть сериализованными, что может быть то, что вы хотите (в зависимости от сделанного обновления), или создаст очень узкое место в этой таблице. Если бы все сделали это в занятой таблице с длительными транзакциями, это могло бы вызвать значительные задержки в приложении.
Как и во всех функциях SQL, при правильном использовании они могут быть мощными, но неправильное использование функции/подсказки может вызвать серьезные проблемы. Я предпочитаю использовать подсказки в качестве последнего средства, когда мне приходится переопределять движок, а не как подход по умолчанию.
Изменить как запрошено: протестировано в SQL 2005, 2008, 2008R2 (все предприятия) - все установлено по довольно многим настройкам по умолчанию, тестовая база данных, созданная с использованием всех значений по умолчанию (просто введите имя только для базы данных).