Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Gattaka, Вы писали: G>>Сейчас вам возразят, что для интеграции приложений шаринг базы данных не самый удачный подход. S>Конечно. Даже с одним приложением всегда есть риск разъехаться в версиях базы и клиента. А когда у нас N приложений, да ещё и на разных языках, то обязательно нужен App Server между данными и клиентами, который гарантирует консистентность бизнес-логики.
Ну так проблема версий сервера везде существует. Разве не может получится разных версий API и клиентов? Запросто... В БД вы просто делаете таблицу с текущим номером версии схемы и остальные приложения в эту таблицу смотрят. Делов то... В случае с сервером с АPI используется аналогичный подход, так что это не то чем уж так разительно подходы отличаются.
S>В таком сценарии использование ХП — это попытка превратить RDBMS в тот самый апп-сервер. Т.е. клиентам закрывают доступ к таблицам; в лучшем случае даём read-only, хотя даже это адски опасно (потому что всегда есть риск, что мы добавили колоночку типа IsDeleted, а где-то в углу завалялся клиент на дельфи, который ничего про неё не знает, и продолжает хреначить репорты с неуловимо отличающимися от официальных цифр данными). S>Пусть фигачат хранимки.
DML — нужно запрещать... У вас ведь с App сервером тоже никто контракт внезапно поменять не может. Добавить поле в DTO IsDeleted?
S>Тут мы быстро приезжаем в то, что SQL Server — это плохой AppServer. Во-первых, у него неудачный протокол взаимодействия. Он категорически не может работать с недоверенными клиентами — достаточно сделать begin tran, выполнить процедурку, и оставить соединение открытым, чтобы все остальные ушли курить. S>Во-вторых, стандартные ХП написаны в соответствии с парадигмой RPC, неработоспособность которой в сетях уже не обсосал только ленивый. S>Банальная штука — ну вот есть у вас процедура, которая должна помечать узлы (или что вы там рассказывали про 700000 записей в своей задаче?...). S>Вот я её с клиента позвал. А в ответ мне прилетает connection reset by peer. Что-то там в сеточке взглюкнуло. Что мне делать? Транзакция сработала или таки нет? S>Для борьбы с этим 15 лет назад придумали REST, где можно обеспечить идемпотентность. S>Вот вы сходу сможете написать свою процедуру идемпотентной? А как отличить идемпотентную от безопасной, и обе от небезопасной? S>В итоге, написание клиента, который имеет гарантированную семантику, превращается из лёгкого и приятного занятия в титанический труд по оборачиванию вызовов во всяческие стратегии. Либо имеем приложение, которое работает кое-как — то есть периодически его надо перезапускать, и руками/глазами смотреть, что из последних действий надо повторять. S>Чтобы сделать к SQL Server RESTful API на ХП, надо много и упорно трудиться. И всё равно получится не так хорошо, как поверх существующих платформ. Не обязательно WCF — выбор сейчас богатый.
Зато есть преимущества, которые никто больше не может перекрыть. Это скорость. И огромная куча функционала под капотом. Мне, например, нравится пример с коллекцией в памяти, которую куча потоков модифицирует в памяти. Как организоывать блокировки? Для каждой строчки read-write lock, а блокировки на диапозоны, а что насчет эскалации блокировок. В SQL Server этот код уже написан, отлажен и работает максимально эффективно. Если вы будете делать что-то аналогичное, то либо потратите кучу времени и напишите кучу кода, либо получите неэффективное решение.
В случае с SQL Server у вас данные в едином месте и управляются единым кодом — там все максимально эффективно, нет лишних сериализаций, переливаний из сущностей в DTO и т.п.