Может ли кто-нибудь объяснить последствия использования with (nolock)
запросов, когда вы должны / не должны использовать его?
Например, если у вас есть банковское приложение с высокой скоростью транзакций и большим количеством данных в определенных таблицах, в каких типах запросов все будет нормально? Есть ли случаи, когда вы всегда должны использовать его / никогда не использовать?
sql-server
nolock
Энди Уайт
источник
источник
Ответы:
WITH (NOLOCK) является эквивалентом использования READ UNCOMMITED в качестве уровня изоляции транзакции. Таким образом, вы рискуете прочитать незафиксированную строку, которая впоследствии откатывается, то есть данные, которые никогда не попадали в базу данных. Таким образом, хотя он может предотвратить блокировку чтения другими операциями, он сопряжен с риском. В банковском приложении с высокой скоростью транзакций это, вероятно, не будет правильным решением для любой проблемы, которую вы пытаетесь решить с его помощью, IMHO.
источник
NOLOCK
с,SELECT
вы рискуете возвращать одни и те же строки более одного раза (дублированные данные), если данные когда-либо вставляются (или обновляются) в таблицу при выполнении выбора.Вопрос в том, что хуже:
Для финансовых баз данных тупики намного хуже, чем неправильные значения. Я знаю, это звучит задом наперед, но выслушай меня. Традиционный пример транзакций БД - вы обновляете две строки, вычитая из одной и добавляя к другой. Это не правильно.
В финансовой базе данных вы используете бизнес-операции. Это означает добавление одной строки к каждой учетной записи. Крайне важно, чтобы эти транзакции были завершены и строки были успешно записаны.
Временное неправильное получение баланса счета не имеет большого значения, для этого и нужна выверка на конец дня. А овердрафт со счета гораздо чаще возникает из-за одновременного использования двух банкоматов, чем из-за незафиксированного чтения из базы данных.
Тем не менее, SQL Server 2005 исправил большинство ошибок, которые сделали
NOLOCK
необходимыми. Поэтому, если вы не используете SQL Server 2000 или более раннюю версию, вам это не нужно.Дальнейшее чтение
версий на уровне строк
источник
К сожалению, речь идет не только о чтении незафиксированных данных. В фоновом режиме вы можете закончить чтение страниц дважды (в случае разбиения страницы), или вы можете пропустить страницы в целом. Таким образом, ваши результаты могут быть сильно искажены.
Проверять, выписываться статью Ицик Бен-Ган . Вот выдержка:
источник
Пример учебника для законного использования подсказки nolock - выборка отчетов для базы данных OLTP с высоким обновлением.
Взять актуальный пример. Если крупный крупный банк США хотел запустить почасовой отчет в поисках первых признаков уровня города в банке, запрос nolock мог бы сканировать таблицы транзакций, суммирующие депозиты и снятие наличных по городам. Для такого отчета небольшой процент ошибок, вызванных откатом транзакций обновления, не уменьшит значение отчета.
источник
Не уверен, почему вы не заключаете финансовые транзакции в транзакции базы данных (например, когда вы переводите средства с одного счета на другой - вы не фиксируете одну сторону транзакции за раз - именно поэтому существуют явные транзакции). Даже если ваш код предназначен для бизнес-транзакций в том виде, в каком он есть, все транзакционные базы данных могут выполнять неявные откаты в случае ошибок или сбоев. Я думаю, что это обсуждение над вашей головой.
Если у вас есть проблемы с блокировкой, реализуйте управление версиями и очистите ваш код.
Без блокировки не только возвращает неправильные значения, он возвращает фантомные записи и дубликаты.
Это распространенное заблуждение, что это всегда заставляет запросы выполняться быстрее. Если в таблице нет блокировки записи, это не имеет значения. Если в таблице есть блокировки, это может сделать запрос быстрее, но есть причина, по которой блокировки были изобретены в первую очередь.
Справедливости ради, вот два специальных сценария, где подсказка Nolock может обеспечить полезность
1) База данных SQL Server до 2005 года, которая должна выполнять длинный запрос к действующей базе данных OLTP, это может быть единственным способом
2) Плохо написанное приложение, которое блокирует записи и возвращает управление пользовательскому интерфейсу, а читатели блокируются на неопределенный срок. Nolock может быть полезен в этом случае, если приложение не может быть исправлено (стороннее и т. Д.), А база данных - до 2005 года, или управление версиями невозможно
источник
NOLOCK
эквивалентноREAD UNCOMMITTED
, однако Microsoft говорит, что вы не должны использовать его дляUPDATE
илиDELETE
заявления:http://msdn.microsoft.com/en-us/library/ms187373.aspx
Эта статья относится к SQL Server 2005, поэтому поддержка
NOLOCK
существует, если вы используете эту версию. Для того, чтобы обеспечить ваш код на будущее (при условии, что вы решили использовать грязное чтение), вы можете использовать это в своих хранимых процедурах:SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
источник
Вы можете использовать его, когда вы только читаете данные, и вам неважно, возвращаете ли вы данные, которые еще не зафиксированы.
Это может быть быстрее при операции чтения, но я не могу точно сказать, насколько.
В общем, я рекомендую не использовать его - чтение незафиксированных данных в лучшем случае может быть немного запутанным.
источник
Другой случай, когда обычно все в порядке, - это база данных отчетов, где данные, возможно, уже устарели, а записи просто не происходят. Однако в этом случае администратор должен установить этот параметр на уровне базы данных или таблицы, изменив уровень изоляции по умолчанию.
В общем случае вы можете использовать его , когда вы очень уверены , что это нормально читать старые данные. Важно помнить, что очень легко ошибиться . Например, даже если в момент написания запроса все в порядке, вы уверены, что в будущем что-то не изменится в базе данных, чтобы сделать эти обновления более важными?
Я также расскажу о том, что это, вероятно, не очень хорошая идея в банковском приложении. Или приложение инвентаря. Или где угодно, вы думаете о транзакциях.
источник
Простой ответ - всякий раз, когда ваш SQL не изменяет данные, и у вас есть запрос, который может помешать другой деятельности (через блокировку).
Это стоит учитывать для любых запросов, используемых для отчетов, особенно если запрос занимает, скажем, более 1 секунды.
Это особенно полезно, если у вас есть отчеты типа OLAP, работающие с базой данных OLTP.
Первый вопрос, который нужно задать: «почему я об этом беспокоюсь?» По моему опыту, фальсификация поведения блокировки по умолчанию часто имеет место, когда кто-то находится в режиме «попробуй что-нибудь», и это один случай, когда неожиданные последствия не исключены. Слишком часто это случай преждевременной оптимизации и может слишком легко остаться встроенным в приложение «на всякий случай». Важно понимать, почему вы это делаете, какую проблему это решает и есть ли у вас эта проблема.
источник
Короткий ответ:
Используйте только
WITH (NOLOCK)
в операторе SELECT для таблиц с кластерным индексом.Длинный ответ:
WITH (NOLOCK) часто используется как магический способ ускорить чтение из базы данных.
Результирующий набор может содержать строки, которые еще не были зафиксированы и которые впоследствии часто откатываются.
Если WITH (NOLOCK) применяется к таблице, имеющей некластеризованный индекс, то индексы строк могут быть изменены другими транзакциями, поскольку данные строк передаются в таблицу результатов. Это означает, что в наборе результатов могут отсутствовать строки или отображаться одна и та же строка несколько раз.
READ COMMITTED добавляет дополнительную проблему, когда данные повреждены в одном столбце, когда несколько пользователей одновременно изменяют одну и ту же ячейку.
источник
READ UNCOMITTED
не повлияет на него вообще. Есть причина, по которой он был включен в стандарт ANSI.Мои 2 цента - это имеет смысл использовать
WITH (NOLOCK
), когда вам нужно создавать отчеты. На этом этапе данные не сильно изменятся, и вы не захотите блокировать эти записи.источник
Если вы обрабатываете финансовые транзакции, вы никогда не захотите их использовать
nolock
.nolock
Лучше всего использовать для выбора из больших таблиц, которые имеют много обновлений, и вам все равно, может ли полученная запись устареть.Финансовые записи (и почти все другие записи в большинстве приложений)
nolock
могут привести к хаосу, поскольку вы потенциально можете прочитать данные из записи, в которую они были записаны, и не получить правильные данные.источник
Я использовал, чтобы получить "следующую партию" для вещей, чтобы сделать. В данном случае не имеет значения, какой именно элемент, и у меня много пользователей, выполняющих этот же запрос.
источник
Используйте nolock, когда вы в порядке с «грязными» данными. Это означает, что nolock может также считывать данные, которые находятся в процессе изменения и / или незафиксированные данные.
Как правило, не рекомендуется использовать его в среде с высокими транзакциями, и поэтому он не является параметром по умолчанию для запроса.
источник
Я использую подсказку (nolock), особенно в базах данных SQLServer 2000 с высокой активностью. Однако я не уверен, что это необходимо в SQL Server 2005. Я недавно добавил эту подсказку в SQL Server 2000 по запросу администратора базы данных клиента, потому что он замечал много блокировок записей SPID.
Все, что я могу сказать, это то, что использование подсказки НЕ повредило нам и, похоже, позволило решить проблему блокировки. Администратор базы данных в этом конкретном клиенте в основном настаивал на том, что мы используем подсказку.
Между прочим, базы данных, с которыми я имею дело, являются бэкэндами к корпоративным системам медицинских заявок, поэтому мы говорим о миллионах записей и более 20 таблиц во многих объединениях. Обычно я добавляю подсказку WITH (nolock) для каждой таблицы в соединении (если только это не производная таблица, в этом случае вы не можете использовать эту конкретную подсказку)
источник
Самый простой ответ - простой вопрос - нужны ли ваши результаты для повторения? Если да, то NOLOCKS не подходит ни при каких обстоятельствах
Если вам не нужна повторяемость, то полезны nolocks, особенно если вы не контролируете все процессы, подключающиеся к целевой базе данных.
источник