Что такое " with (nolock)" в SQL Server?

может кто-нибудь объяснить последствия использования with (nolock) на запросы, когда вы должны/не должны использовать его?

например, если у вас есть банковское приложение с высокими ставками транзакций и большим количеством данных в определенных таблицах, в каких типах запросов nolock будет в порядке? Бывали ли случаи, когда вы всегда должны использовать его/никогда не использовать его?

16 ответов


WITH (NOLOCK) эквивалентно использованию READ UNCOMMITED в качестве уровня изоляции транзакции. Таким образом, вы рискуете прочитать незафиксированную строку, которая впоследствии откатывается, т. е. данные, которые никогда не попадали в базу данных. Таким образом, хотя он может предотвратить блокировку чтения другими операциями, он сопряжен с риском. В банковском приложении с высокими ставками транзакций это, вероятно, не будет правильным решением любой проблемы, которую вы пытаетесь решить с помощью IMHO.


вопрос в том, что хуже:

  • тупик, или
  • неверное значение?

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

в финансовой базе данных используются бизнес-транзакции. Это означает добавление одной строки к каждой учетной записи. Он крайне важно, чтобы эти транзакции завершились и строки были успешно записаны.

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

тем не менее, SQL Server 2005 исправил большинство ошибок, которые сделали NOLOCK надо. Так что если вы не использование SQL Server 2000 или более ранних версий не требуется.

Более Дальнеишее Чтение
Управление Версиями На Уровне Строк


пример текстовой книги для законного использования подсказки nolock-это выборка отчета для базы данных OLTP с высоким обновлением.

взять актуальный пример. Если крупный банк на Хай-стрит в США хотел запустить ежечасный отчет, ищущий первые признаки запуска уровня города на банке, запрос nolock мог сканировать таблицы транзакций, суммирующие денежные депозиты и снятие наличных в каждом городе. Для такого отчета крошечный процент ошибок, вызванных откатными транзакциями обновления, не уменьшится значение отчета.


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

проверить статья Ицика Бен-Гана. Вот отрывок:--1-->

" с подсказкой NOLOCK (или установкой уровень изоляции сессии для чтения UNCOMMITTED) вы говорите SQL Server, что вы не ожидаете последовательности, так есть никаких гарантий. Имейте в виду, хотя что "несогласованные данные" не только означает, что вы можете видеть незафиксированные изменения, которые позднее были откатаны, или изменения данных в промежуточном состояние транзакции. он также означает, что в простом запросе сканирование всех данных таблицы / индекса SQL Server может потерять позицию сканирования, или вы может закончиться тем же самым дважды!--9-->. "


Не уверен, почему вы не переносите финансовые транзакции в транзакции базы данных (например, когда вы переводите средства с одного счета на другой - вы не фиксируете одну сторону транзакции одновременно-вот почему существуют явные транзакции). Даже если ваш код является braindead для бизнес-транзакций, как это звучит, все транзакционные базы данных могут выполнять неявные откаты в случае ошибок или сбоев. Я думаю, эта дискуссия закончилась. голова.

Если у вас возникли проблемы с блокировкой, внедрить управление версиями и очистить ваш код.

no lock не только возвращает неправильные значения, он возвращает фантомные записи и дубликаты.

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

справедливости ради, вот два специальных сценария, где подсказка nolock может обеспечить полезность

1) база данных sql server до 2005 года, которая должна выполнять длинный запрос к живой базе данных OLTP это может быть единственным способом

2) плохо написанное приложение, которое блокирует записи и возвращает управление пользовательскому интерфейсу и читателям, заблокировано на неопределенный срок. Nolock может быть полезен здесь, если приложение не может быть исправлено (третья сторона и т. д.), а база данных либо до 2005 года, либо не может быть включить.


NOLOCK эквивалентно READ UNCOMMITTED, однако, Microsoft говорит, что вы не должны использовать UPDATE или DELETE отчетность:

для инструкций UPDATE или DELETE: эта функция будет удалена в будущей версии Microsoft SQL Server. Избегайте использования этой возможности в новых разработках и запланируйте изменение приложений, которые используют эту функцию.

http://msdn.microsoft.com/en-us/library/ms187373.aspx

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

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED


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

В общем случае: вы можете использовать его, когда вы очень конечно, это нормально читать старые данные. Важно помнить, что его очень легко получить, что не так. Например, даже если это нормально во время написания запроса, вы уверены, что в будущем что-то не изменится в базе данных, чтобы сделать эти обновления более важными?

Я также 2nd понятие, что это, вероятно,не хорошая идея в банковском приложении. Или инвентаризации приложение. Или в любом месте, где вы думаете о сделках.


вы можете использовать его, когда вы только читаете данные, и вы действительно не заботитесь о том, Можете ли вы получить обратно данные, которые еще не зафиксированы.

Это может быть быстрее при операции чтения,но я не могу сказать, насколько.

В общем, я рекомендую ее не использовать - чтение незафиксированных данных может быть немного запутанным, в лучшем случае.


простой ответ-всякий раз, когда ваш SQL не изменяет данные, и у вас есть запрос, который может помешать другой деятельности (через блокировку).

Это стоит рассмотреть для любых запросов, используемых для отчетов, особенно если запрос занимает более, скажем, 1 секунды.

Это особенно полезно, если у вас есть отчеты типа OLAP, которые вы используете против базы данных OLTP.

первый вопрос, который нужно задать, это: "почему я беспокоюсь об этом?"по моему опыту, выдумка поведение блокировки по умолчанию часто происходит, когда кто-то находится в режиме "попробуйте что-нибудь", и это один из случаев, когда неожиданные последствия не маловероятны. Слишком часто это случай преждевременной оптимизации и может слишком легко остаться встроенным в приложение "на всякий случай."Важно понять, почему вы это делаете, какую проблему это решает и действительно ли у вас есть проблема.


мои 2 цента - имеет смысл использовать WITH (NOLOCK) когда вам нужно создать отчеты. На данный момент данные не сильно изменятся, и вы не захотите блокировать эти записи.


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

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


Я использовал для получения "следующей партии" для дел. В этом случае не имеет значения, какой именно элемент, и у меня много пользователей, выполняющих этот же запрос.


используйте nolock, когда вы в порядке с "грязными" данными. Это означает, что nolock также может считывать данные, которые находятся в процессе изменения и/или незафиксированных данных.

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


Я использую с подсказкой (nolock), особенно в базах данных SQLServer 2000 с высокой активностью. Однако я не уверен, что это необходимо в SQL Server 2005. Недавно я добавил этот намек в SQL Server 2000 по запросу DBA клиента, потому что он заметил много блокировок записи SPID.

все, что я могу сказать, это то, что использование подсказки не повредило нам и, похоже, заставило проблему блокировки решить себя. DBA на этом конкретном клиенте в основном настаивал на том, чтобы мы использовали намек.

кстати, базы данных, с которыми я имею дело, являются фоном для корпоративных систем медицинских претензий, поэтому мы говорим о миллионах записей и 20+ таблицах во многих соединениях. Обычно я добавляю подсказку WITH (nolock) для каждой таблицы в соединении (если это не производная таблица, и в этом случае вы не можете использовать эту конкретную подсказку)


короткий ответ:

никогда не используйте WITH (NOLOCK).

ответ:

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

результирующий набор может содержать строки, которые еще не были зафиксированы,которые часто позже откатываются.

ошибка или результирующий набор могут быть пустыми, отсутствовать строки или отображать одну и ту же строку несколько раз.

это потому, что другие транзакции перемещают данные одновременно с их чтением.

Read COMMITTED добавляет дополнительную проблему, когда данные повреждены в одном столбце, где несколько пользователей изменяют одну и ту же ячейку одновременно.

есть и другие побочные эффекты, которые приводят к тому, что вы жертвуете увеличением скорости, которое вы надеялись получить в первую очередь.

можно утверждать, что его можно использовать в местах, где вы можете сойдет с рук, но какой в этом смысл? Я не могу придумать ни одной ситуации, когда поврежденные данные приемлемы.

никогда никогда не используйте NOLOCK никогда.

(когда-нибудь)


самый простой ответ-простой вопрос - вам нужно, чтобы ваши результаты были повторяемыми? Если да, то NOLOCKS не подходит ни при каких обстоятельствах

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