Используете подсказку NOLOCK в EF4? - PullRequest
8 голосов
/ 26 января 2010

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

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

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

Спасибо.

Ответы [ 6 ]

30 голосов
/ 26 января 2010

NOLOCK = "ЧИТАТЬ НЕОГРАНИЧЕННЫЙ" = грязное чтение

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

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

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

11 голосов
/ 30 июля 2010

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

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

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

9 голосов
/ 03 января 2011

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

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

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

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

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

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

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

3 голосов
/ 17 января 2013

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

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

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

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

2 голосов
/ 08 мая 2012

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

0 голосов
/ 26 января 2010

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

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

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

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

...