Re[31]: Entity Framework за! и против!
От: vdimas Россия  
Дата: 30.07.14 12:52
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>С .NET 2.0 SqlConnection поддерживает аснхронное чтение. Ты с 2005 года .NET то видел вообще?


Вот, опять ты подставился. Это "асинхронное" чтение в дотнете сделано по технологии Completion Routines. Это предъявляет определённые требования к потоку, в котором это происходит. В результате, твоя асинхронщина подключается только тогда, когда ты вызываешь асинхронное же АПИ, иначе событие Completion Routines никогда не получит шанса на обработку. Более того, для тех же злополучных блобов, когда ты открывал к нему Stream и читал из него асинхронно, то там асинхронность эмулировалась на стороне дотнета, реально её не было. И именно там я обнаружил ошибку.

И да. Упомянутый мною баг я обнаружил на 2-м дотнете, ес-но. И мне пришлось изучить код дотнетного клиентского драйвера под MS SQL фактически наизусть. А твоя распальцовка попросту смешна, бо ты в глаза не его видел и понятие не имеешь, как он работает.

Далее. В Windows есть минимум 4 способа организации асинхронщины. Так вот, OLEDB давал "правильную" работу с TCP-соединением, даже при обычном, т.е. блокирующем чтении из него. Потому что overlapped API позволяет не только ожидать готовности данных, но может "само" заливать данные в заранее подготовленные буфера.

Ты ведь совсем не в курсе, что в дотнете до сих пор НЕТ нормального асинхронного ввода-вывода, в т.ч. у дров БД. (Вернее — в первую очередь у дров БД, бо самые большие бока с асинхронщиной в дотнете — это сетка). Ты ведь не в курсе, что типичная дотнетная асинхронщина сидит на простом сигналинге готовности, но не использует ср-ва ОС по фоновому заливу или чтению данных, которое происходит прямо по прерываниям устройств прямо из ядра, не заходя в юзверское кольцо?

Только в дотнете 3.5 появился первый более-менее настоящий асинхронный сокет, а не та порнография, что была до этого.
Курить тут:
http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs(v=vs.90).aspx

Это реализация асинхронщины через Completion Ports. Ох мы и погоняли эту реализацию. Потом сравнили со своей, нейтивной. Скажем так, более неэффективной и тормозной реализации, чем по ссылке, свет еще не видел. Я тебе ОЧЕНЬ рекомендую изучить все то, что связано с SocketAsyncEventArgs, пройдись декомпилятором и посмотри, что и как там происходит... потому что на прямо сейчас ты настолько не в теме, насколько может быть не в теме человек, который вообще никогда не видел дотнета. Ужаснись тому коду, который составляет "самый эффективный способ асинхронных сокетов для дотнет". Это ужас и бред одновременно. Начиная с того, что SocketAsyncEventArgs используется вовсе не как привычный EventArgs, а как обычный объект, который надо создавать на стороне клиента библиотеки, а не получать его в событиях готовым, как это принято в XxxEventArgs. Кароч, криво всё, что можно. Всё тормозит, производительность никакая. Хотя, намного лучше, чем обычные дотнетные BeginRead/EndRead и прочий мусор, который чаще всего используется в расширениях async/await дотнета, хотя является самым неэффективным вариантом асинхронщины как таковой.

Кароч, я подробно знаю, в отличие от вас всех, внутренние механизмы библиотек ввода/вывода дотнета. Прекрасно, в отличие от вас, понимаю их ограничения. Прекрасно понимаю, почему ты, как клиент библиотеки, не имеешь возможности настраивать способ использования IO/CP или параметров overlapped в АПИ виндов. Прекрасно понимаю, почему самый эффективный сценарий асинхронности на дотнете (чтение/запись, не выходя из ядра) из дотнета недоступны. Вернее, доступны, через пины буферов, но когда кол-во пинов ужасащее (а для сервака это ВСЕГДА так, бо есть куча буферов на одно соединение, помноженное на кучу соединений), то сам дотнет начинает безбожно тормозить.


G>>>Но даже если база не падает, то твой запрос, даже самый безобидный, может отвалиться по куче причин. Начиная от банального дедлока, заканчивая происками resource governor.

V>>Дедлок в базе? )))
G>Да легко

Как? "Длинные транзакции"? )))


V>>Тут кто-то пишет на курсорах пошагово? Не распланировав уровни блокировки данных? А, не! Тут же все крутые Linq-программисты, всё делается одним запросом, откуда дедлок-то?

G>Дедлок можно схватить с обычным select в одной сессии и insert в другой, даже на read commited. .NET не при чем.

Это ПРИНЦИПИАЛЬНО НЕВОЗМОЖНО при одном и том же уровне блокирования. Вот просто математически не существует такого способа, хоть ты убейся. А если у тебя разные уровни блокирования к одним и тем же таблицам... гы-гы-гы... я тут даже не знаю, что сказать. Это похлеще выхода за пределы массива в С++.


G>Но я понимаю что ты не в курсе.


Я тоже кое-чего уже понимаю. Хотя, относительно конкретно тебя мне всё понятно уже слишком давно. Ты подставляешься примерно каждый второй свой пост. Ты о гранулярности блокировок слышал хоть что-нить хоть когда-нить? Я уже не о СУБД спрашиваю, а об обычной разработке. Опиши, плиз, простейший алгоритм избегать дедлока при обычной твоей разработке? Вот у тебя пара ресурсов. Процесс 1 лочит ресурс 1 и лезет в ресурс 2, в то же самое время процесс 2 уже залочил ресурс 2 и лезет в ресурс 1. Какой алгоритм недопущений дедлока в этой ситуации?


G>Судя по сообщениям только у тебя и глючило. Учитывая твой уровень знаний СУБД, мне кажется что проблема вовсе не в .NET.


Судя по экранам с ошибкой на этом сайте и не только на этом — на дотнете глючит постоянно.


V>>Ну конечно же! Предикаты и проекции — самые изменяемый части!!! Методом несложной дедукции выводим, что джоины — это самые устойчивые конструкции в разных запросах. А что я предлагал запихивать во вьюхи? Ах, блин! Неужели их же?

G>И что ты собираешься выйграть от этого? Сокращение запросов на 3 строки? В чем смысл? Все равно придется генерить предикаты и проекции

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


V>>Если для полной инфы по товару надо сделать джоин по примерно 5-ти таблицам (и это еще скромно), то я обязательно сделаю такую вьюху, где будет описан этот джоин. И буду пользовать её в сотнях разных запросов. Примаешь, вьюха для сервака "прозрачна". Т.е. это как текстовый макрос. Не бойся, что вьюха "выбирает" все поля, а тебе нужно в проекции всего пяток, нифига лишнего на самом деле не выбирается. Это просто уже предкомпиллированный приличный кусок SQL-конструкции.

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

Избежишь копипасты.


V>>В том-то и дело, что не существует в природе "запросов с параметрами". Есть просто запросы и есть хранимки с параметрами. ))

G>
G>Существуют, эдак с 2000 года. Просто ты о них не знаешь. Более того в .NET используются с самой первой версии.

Нет. Это заморочки драйвера. Просто ты об этом не знаешь.

V>>Существует драйвер базы и временная хранимка уровня соединения на той стороне. Просто драйвер базы даёт такой синтаксис, что как бы просто запрос с как бы параметрами. Поэтому всё, что верно для хранимок, верно и для т.н. "запросов с параметрами".

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

Просто ты об этом не знаешь.

V>>Потому что параметры в запросы могут подставляться разным способом. В случае твоего Linq на каждое новое значение ID может генериться тупо другой итоговый текст с другим числовым ID, а не параметром.

G>Может, но не генерируется. Провайдеры не идиоты пишут к счастью.

По-факту, кста, идиоты. Потому что зачастую новое числовое значение прямо в тексте эффективнее подставляемого параметра. И ты сам же верно говорил — почему.

V>>И как ты предлагаешь держать это всё под контролем сквозь всё приложение, где у нас будет запрос с параметром, а где тупо другой текст с другим числовым ID?

G>Ты никогда не сможешь все держать под контролем.

Вообще-то смогу. Я тебя проверял.

G>Ты всегда отдаешь часть контроля в обен на скорость разработки. В языке C отдали контроль над регистрами и над стеком. В C++ отдали контроль над способом передачи структур и генерацией кода, итд. Linq отдает контроль над гененрацией запроса, а авторы провайдеров берут на себя обязательства генерировать хорошие запросы. И как обычно у автоматического генератора получается лучше, чем у среднего программиста.


Еще раз. КАК мне отделить места в выражении Linq, использующем переменные и генерящем для них параметры от мест, где вместо параметров непосредственно подставляются значения переменных? Это тебе домашнее задание, разработчик ты наш.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.