Используете NOLOCK Hint в EF4?

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

Я читал различные идеи о том, как сделать это в EF4, но все они кажутся обходными и не санкционированными Microsoft или EF4. Каков "официальный ответ Microsoft" тому, кто хочет, чтобы их операторы SELECT включали подсказку NOLOCK при использовании LINQ-to-SQL / LINQ-to-Entities и EF4?

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

Спасибо.


person John    schedule 26.01.2010    source источник
comment
Я согласен с советом в теме, на которую вы ссылаетесь: используйте SNAPSHOT/READ_COMMITTED, а не NOLOCK. Я считаю NOLOCK в основном устаревшим - не то чтобы это когда-либо было хорошей идеей, поскольку это делает ваши транзакции не-ACID. См. Также http://stackoverflow.com/questions/1452996/is-the-nolock-sql-server-hint-bad-practice Кроме того, в этой статье перечислены преимущества и недостатки sqlmag.com/Articles/ArticleID/93075/93075.html?Ad=1   -  person Craig Stuntz    schedule 26.01.2010


Ответы (6)


NOLOCK = "READ UNCOMMITTED" = грязное чтение

Я предполагаю, что MS знает, почему они выбрали уровень изоляции по умолчанию как «READ COMMITTED»

NOLOCK, как и любую подсказку, следует использовать очень разумно: не по умолчанию.

Ваш администратор базы данных - кукла. См. Это (SO): Что может произойти в результате использования (nolock) для каждого оператора SELECT на сервере SQL?. Если вы работаете в банке или любом учреждении, где у меня может быть счет, сообщите мне, и я смогу его закрыть.

person gbn    schedule 26.01.2010
comment
+1 Я сам собирался опубликовать несколько неприятных комментариев о dba, но я думаю, что "muppet" подводит итог просто отлично :) - person Remus Rusanu; 26.01.2010
comment
Я думаю, что вы маппет, если хотите делать каждый выбор в базе данных с блокировкой. Я на 100% сторонник блокировки таблиц, требующих согласованности транзакций, но если у меня есть таблица состояния или таблица пользователей, любая таблица более статическая, чем динамическая, почему я хочу, чтобы другие не читали ее, пока я ее читаю? И да, чтение / выбор блокирует таблицу, если вы этого не знали. Таким образом, даже несмотря на то, что READ COMMITTED является значением по умолчанию, и я на 100% согласен с этим, есть случаи и ситуации, которые требуют блокировки, и они не так уж редки. Не все запросы, но по крайней мере некоторые - person Ryk; 06.02.2013
comment
@Ryk: Какая разница, если вы не блокируете других читателей? По-настоящему статические таблицы лучше подходят для файловой группы только для чтения. Для нестатических таблиц вы можете читать данные, которые со временем могут измениться. Достаточно одного грязного чтения, которое дает неверный результат запроса, который может иметь серьезные последствия. Но ведь очевидно, что вы не работаете с системами, где точность имеет первостепенное значение. - person gbn; 06.02.2013
comment
@Ryk; Пожалуйста, прочтите вопрос еще раз. gbn предполагает, что этот администратор баз данных является маппетом, потому что этот администратор баз данных говорит, что мы должны использовать подсказку NOLOCK во всех наших операторах SELECT. Он (gbn) также советует использовать любые подсказки (включая NOLOCK) с умом. Не никогда. Также нельзя делать каждый выбор в базе данных с блокировкой. - person ypercubeᵀᴹ; 06.02.2013
comment
@Ryk Также не стесняйтесь изучать вклад gbn, чтобы вы могли оценить, что он знает, а что нет. (Прочтите: не надо оскорблять.) - person dezso; 06.02.2013
comment
@gbn Просто прочтите мои первые 5 слов, и вы увидите, что я не оскорблял вас, но утверждение muppet относится к стереотипам принятия того, что значение по умолчанию READ COMMITTED - единственное верное решение, и вы не можете отклоняться от него. Конечно, значение по умолчанию будет работать для 98% людей, но я работаю над базами данных, которые выполняют порядка 90 000 транзакций в секунду, и если вы оптимистично заблокируете других читателей, результат может быть обработан за 2 дня по сравнению с . 2 часа. Так что НИКАКОГО оскорбления не имелось в виду и не было направлено на gbn, извините, если получилось неправильно - person Ryk; 07.02.2013

Я разработчик в группе инструментов в организации SQL в Microsoft. Я никоим образом не уполномочен делать какие-либо официальные заявления, и я уверен, что на SO есть люди, которые знают об этих вещах больше, чем я. Тем не менее, я предлагаю дружеское практическое правило по теме «Преждевременная оптимизация - корень всех зол»:

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

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

person RyanHennig    schedule 30.07.2010

EF4 в настоящее время не имеет встроенного способа сделать это, ЕСЛИ ef4 генерирует все ваши запросы.

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

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

Похоже, вас попросили заблокировать ВСЕ варианты выбора. Хотя я согласен с предыдущим постером, что это может быть опасно, если у вас есть ЛЮБЫЕ транзакции, которые должны быть транзакциями, я не согласен, что администратор баз данных автоматически превращается в маппет. Возможно, вы просто используете CMS, которая отлично подходит для грязного чтения. Вы можете изменить УРОВЕНЬ ИЗОЛЯЦИИ для всей базы данных, что может иметь тот же эффект.

Администратор базы данных, возможно, рекомендовал nolock для операций, которые были ТОЛЬКО выбранными (что нормально, особенно если есть ORM, который неправильно загружается и делает некоторые хитрые дампы данных). Самым забавным в этом комментарии маппета является то, что сам Stack Overflow запускает SQL-сервер в режиме READ UNCOMMITTED. Думаете, вам нужно найти другое место, чтобы получить ответы на свои проблемы?

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

Информация об уровнях изоляции

person Gats    schedule 03.01.2011

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

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

Если вы обнаружите, что вам нужно сделать данные доступными через EF и вам нужно NOLOCKs, вы всегда можете создать представления с NOLOCK подсказками и предоставить представление в EF вместо базовой таблицы. То же самое можно сделать с хранимыми процедурами. Эти методы, вероятно, будут немного проще, если вы используете подход Code First.

Но я думаю, что одна ошибка, которую делают многие люди с EF, заключается в том, что они считают, что объектная модель EF должна напрямую отображаться на физическую (табличную) модель в базе данных. Это не так, и именно здесь ваш администратор баз данных вступает в игру. Позвольте ему спроектировать вашу физическую модель, и вы вместе работаете над абстрагированием своей логической модели данных, которая отображается на вашу объектную модель в EF.

person Shane    schedule 17.01.2013

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

person Wil Bloodworth    schedule 07.05.2012

Я знаю, что это не ответ на ваш вопрос, но я просто хотел добавить его.

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

Однако единственный способ быть уверенным - это для администратора базы данных работать над приложением вместе с вами и построить поверхность БД, которую он хотел бы представить приложению. Если он хочет, чтобы критические таблицы запрашивались как READ UNCOMMITTED, он должен помочь предоставить набор хранимых процедур с правильным уровнем доступа и изоляции.

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

person womp    schedule 26.01.2010