SQL Server подсказка NOLOCK и ROWLOCK
В настоящее время я исследую раздражающую проблему на моем сайте. Мы регулярно раздаем призы на сайте, но для участия в конкурсе люди должны войти в систему. Таким образом, сайт становится очень занятым время от времени. Я обнаружил, что когда многие люди пытаются войти в систему и зарегистрироваться, я получаю кучу ошибок о взаимоблокировках функций UpdateUser, CheckPassword и GetUser, тогда сервер становится слишком занятым, и другие запросы начинают истекать по времени.
Когда я изучил хранимые процедуры, я обнаружил, что ROWLOCK используется в UpdateUser. Эти ROWLOCK-ы вызывают тупик? или только выбор приведет к тупику?
Я думал об использовании NOLOCK для моей ситуации, но после небольшого исследования, очевидно, это не рекомендуется...
2 ответа
Как уже объяснил Барри, эти две подсказки могут дополнять друг друга, но они обычно используются в разных контекстах и для решения различных проблем конкуренции за ресурсы.
WITH (NOLOCK) сообщает серверу использовать уровень изоляции транзакции READ UNCOMMITTED, что означает, что вы подвержены риску чтения незафиксированных ("грязных") строк, которые могут впоследствии откатиться и, следовательно, никогда не существовать. Это предотвращает классические блокировки при чтении, но за счет получения неверных данных.
Если существует вероятность того, что операции GetUser или CheckPassword могут получить доступ к профилю пользователя, обновляемому с помощью операции UpdateUser, использование WITH (NOLOCK) не рекомендуется.
Подсказка таблицы WITH (ROWLOCK) может использоваться с инструкциями SELECT, INSERT, UPDATE и DELETE, чтобы дать серверу указание применять только Range-Lock(s) к изменяемым или добавляемым строкам и избегать эскалации блокировки. на страницу или уровень таблицы. Остальные строки не заблокированы и могут быть доступны другим запросом.
Однако если уровень изоляции транзакции по умолчанию на сервере SQL Server READ COMMITTED или более ограничительный, а SNAPSHOT READS не включены, то активная транзакция INSERT, UPDATE или DELETE может по-прежнему блокировать запрос SELECT, если условия поиска совпадают или перекрываются.
используйте подсказку, когда запрос затронет только одну или только несколько строк, чтобы защитить блокировку от строк, которые не будут удалены запросом. Это позволит другому запросу одновременно читать несвязанные строки вместо того, чтобы ждать завершения удаления.
Если вы используете его в запросе, который удалит много строк, это может привести к снижению производительности, поскольку база данных попытается избежать увеличения блокировок до большего объема, даже если это было бы более эффективно.
WITH (NOLOCK) используется с операторами SELECT, когда чувствительность ко времени при извлечении данных с точностью до микросекунды не является эксцентричной или выбор новой добавленной записи не выполняется должным образом.
WITH (ROWLOCK) используется операторами UPDATE, чтобы удерживать блокировку строки на уровне блокировки строк, а не повышать ее до более чем одной строки или даже блокировки таблицы.
Вы всегда должны использовать как в операторах выбора, так и в операторах обновления, а также вам нужно правильно создавать индексы, кэшировать повторяющиеся данные, чтобы не выполнять быстрый запрос базы данных на предмет данных, которые мало меняются, и взглянуть на логику входа в систему, чтобы определить, если он не выполняет ненужную регистрацию данных, а также проверьте журналы ошибок SQL на наличие ошибок, которые могут замедлить доступ к вашему веб-сайту.