16 ответов:
WITH (NOLOCK) - это эквивалент использования READ UNCOMMITED в качестве уровня изоляции транзакций. Таким образом, вы рискуете прочитать незафиксированную строку, которая впоследствии откатывается, т. е. данные, которые никогда не попадали в базу данных. Таким образом, хотя он может предотвратить блокировку чтения другими операциями, он сопряжен с риском. В банковском приложении с высокими ставками транзакций это, вероятно, не будет правильным решением любой проблемы, которую вы пытаетесь решить с помощью IMHO.
вопрос в том, что хуже:
- тупик, или
- неверное значение?
для финансовых баз данных взаимоблокировки гораздо хуже, чем неправильные значения. Я знаю, что это звучит задом наперед, но выслушай меня. Традиционный пример транзакций БД-это обновление двух строк, вычитание из одной и добавление в другую. Это неправильно.
в финансовой базе данных используются бизнес-транзакции. Это означает добавление одной строки в каждую учетную запись. Оно крайне важно, чтобы эти транзакции были завершены и строки были успешно записаны.
получение баланса счета временно неправильно не имеет большого значения, это то, что в конце дня выверки. И овердрафт со счета гораздо более вероятен, потому что два банкомата используются одновременно, чем из-за незафиксированного чтения из базы данных.
тем не менее, SQL Server 2005 исправил большинство ошибок, которые сделали
NOLOCKнадо. Так что если вы не с помощью SQL Server 2000 или ранее, вам не нужен.Более Дальнеишее Чтение
Управление Версиями На Уровне Строк
пример учебника для законного использования подсказки nolock-это выборка отчетов из базы данных OLTP с высоким обновлением.
чтобы взять актуальный пример. Если крупный американский банк high street хотел запустить почасовой отчет, ищущий первые признаки запуска уровня города в банке, запрос nolock мог сканировать таблицы транзакций, суммирующие денежные депозиты и снятие наличных в каждом городе. Для такого отчета крошечный процент ошибок, вызванных откатными транзакциями обновления, не уменьшится значение отчета.
к сожалению, речь идет не только о чтении незафиксированных данных. В фоновом режиме вы можете в конечном итоге читать страницы дважды (в случае разделения страницы), или вы можете пропустить страницы вообще. Так что ваши результаты могут быть сильно искажены.
проверить статья Ицика Бен-Гана. Вот выдержка:
" с подсказкой NOLOCK (или установкой уровень изоляции сеанса для чтения UNCOMMITTED) вы говорите SQL Server, что вы не ожидаете последовательности, так что там никаких гарантий. Имейте в виду, хотя что "противоречивые данные" не только означает, что вы можете видеть незафиксированные изменения, которые позже были откатаны, или изменения данных в промежуточном звене состояние сделки. он также означает, что в простом запросе, что сканирование всех данных таблиц/индексов SQL Server может потерять позицию сканирования, или вы может в конечном итоге получить ту же строку дважды. "
Не уверен, почему вы не переносите финансовые транзакции в транзакции базы данных (например, когда вы переводите средства с одного счета на другой - вы не совершаете одну сторону транзакции одновременно-вот почему существуют явные транзакции). Даже если ваш код является 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
другой случай, когда обычно все в порядке, находится в базе данных отчетов, где данные, возможно, уже состарились и записи просто не происходят. Однако в этом случае администратор должен установить этот параметр на уровне базы данных или таблицы, изменив уровень изоляции по умолчанию.
В общем случае: вы можете использовать его, когда вы очень уверен, что это нормально читать старые данные. Важно помнить, что его очень легко ошибиться. Например, даже если это нормально во время написания запроса, вы уверены, что что-то не изменится в базе данных в будущем, чтобы сделать эти обновления более важными?
Я также 2-й понятие, что это, вероятно,не хорошая идея в банковском приложении. Или приложение инвентаризации. Или в любом месте, где вы думаете о сделках.
вы можете использовать его, когда вы только читаете данные, и вы действительно не заботитесь о том, Можете ли вы получить обратно данные, которые еще не зафиксированы.
Это может быть быстрее на операции чтения, но я действительно не могу сказать, насколько.
В общем, я рекомендую ее не использовать - чтение незафиксированных данных может быть немного запутанным, в лучшем случае.
простой ответ-всякий раз, когда ваш 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 может быть полезен, особенно если у вас нет контроля над всеми процессами, подключающимися к целевой базе данных.
Comments