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

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

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

Ответ 1

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

Ответ 2

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

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

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

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

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

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

Дополнительная литература
Версии уровня строк

Ответ 3

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

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

Ответ 4

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

Ознакомьтесь с статьей ицик Бен-Ган. Вот выдержка:

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

Ответ 5

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

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

Никакая блокировка не только возвращает неправильные значения, она возвращает phantom записи и дубликаты.

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

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

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

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

Ответ 6

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

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

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

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

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Ответ 7

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

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

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

Ответ 8

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

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

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

Ответ 9

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

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

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

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

Ответ 10

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

Ответ 11

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

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

Ответ 12

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

Ответ 13

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

Используйте WITH (NOLOCK) только в операторе SELECT для таблиц с кластерным индексом.

Длинный ответ:

WITH (NOLOCK) часто используется как магический способ ускорить чтение из базы данных.

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

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

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

Ответ 14

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

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

Ответ 15

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

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

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

Ответ 16

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

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