Используете подсказку NOLOCK в EF4?

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

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

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

Благодарю.

6 ответов

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам