Здравствуйте, gandjustas, Вы писали:
G>>>Еще раз. Не путайте суть и форму. Форма будет одинаковая: классы, объекты, интерфесы, наследование. При ООП подходе у вас будет императивный код работы с объектами. При ER — декларативный код работы с сущностями. T>>Ок. Я понял, под er вы подразумеваете не er-модель. Проехали. G>А что вы подразумеваете под ER моделью в программе?
Под ER-моделью я, как ни странно, понимаю ER-модель
G>>>Или вы считаете что нельзя с помощью запросов выразить большенство операций? T>>Можно. Но мне не известо ничего о том как бороться со сложностью в запросах. А они при предлагаемых методах будут сложными. G>Известно. Linq в текущей реализации позоволяет последовательно строить выборку, накладывая дополнительные ограничения. G>В коде выглядит как фильрация коллекции с разными условиями, только самой коллекции нету.
Ясно. Я использовал такой подход в простых сценариях, когда при определенных условиях нужно было применять дополнительное условие.
Но такой подход не всегда применим. В частности, в проекте на котором я сейчас работаю настройки безопасноти (привелегии) хранятся во внешней базе.
T>>То есть каждому пользователю давать свой логин в базе? Ты в курсе, что так делать не рекомендуют? G>Нет, есть таблица, хранящая логины и другие сведения о пользователях. В логах можно ссылкаться на эту таблицу.
А как определить текущего пользователя?
T>>Такие тесты работать будут часами. Главное требование к юнит-тесту — это то, что он работает оч. быстро. Станет работать медленно, никто их запускать не будет. На себе проверено. G>Вам не потребуется эти тесты запускать в совокупноти с unit-тестами приложения. Аудит в БД полностью ортогонален бизнес-логике в коде приложения.
Почему не понадибится? Как иначе проверишь, что определенные действия отражаются в аудит-логе?
G>>>Вы не поняли. Действительно можно будет выполнить ВСЕ запросы в одной транзакции. При использовании ОРМ придется сделать выборку в одной транзакции, а потом коммит в другой. T>>Это еще почему? G>Потому что реализация такая. Linq2SQL и EF так работают.
Открывай TransactionScope и будет одна транзакция. Или я опять что-то не понимаю?
G>>>Можно явно объявить TransactionScope, но тогда её придется явно завершить после вызова SaveChanges. T>>Это сложно? G>Это сложнее чем ОДИН раз явно обявить транзакцию при использовании запросов.
Все равно не вкуриваю. Код с TransactionScope — правтически один-в-один с приводимым тобой кодом. В чем отличие-то?
G>>>При материализации последнего запроса вылетит ошибка и транзакция будет откачена если остатки ушли в минус, а кастомер не VIP.
T>>То есть сначала мы пишем в базу, а потом валидируем? Оригинально G>При таком подходе ВСЯ работа с данными происходит в БД, это нормально.
БД — это всегда узкое место. Если есть возможность делать проверки в бизнесе, они болжны быть сделаны в бизнесе. Неужели эти банальности нужно повторять?
T>>Это точно ты говорил, что материализация плохо отражается на перформансе? G>Это так и есть.
И как это сочетается с тем, что валидацию ты возлагаешь на базу, когда ее можно сделать в бизнесе, что дешевле?
T>>Пусть система состоит из 2-х подсистем: работа с кастомерами, база знаний. T>>Есть кастомер. При регистрации его в системе должен создаться соответствующий раздел в базе знаний. T>>Где (кем) будет проверяться, что созданный раздел создан корректно? G>Наверное тем кто создает раздел. К чему это все?
То есть нужно полагаться на то, что никто не напортачит и сделает все правильно, так?
T>>P.S. На самом деле то, что вы описываете, до боли напоминает transaction script как он назван у Фаулера. Единственное отличие, которое я вижу — это его типизированность. В той же книжке описывается почему с ростом сложности приложения с transaction script-ом становится сложно жить. Рекомендую глянуть, если еще не смотрели. G>Я уже форуме "архитектура" про фаулера отписал. Повторюсь здесь. G>Концептуальная разница между transaction script и dimain model состоит в том как вы хотите вызывать методы бизнес-логики G>Так G>
G>entity.Operation(params)
G>
G>или так G>
G>service.Operation(entity, params)
G>
G>Второй подход гораздо лучше по многим причинам.
Сервисы не отрицают domain model, а дополняют ее.
Развитая доменная модель позволяет защитить целостность данных в доменной модели и сделать код более читаемым, близким к предметной области.
G>А фаулер какю-то неправильную траву курит.
Да они там все такие :
Жена звонит мужу на мобильный:
— Алло, ты где?
— Я в машине, на садовом.
— Ты там осторожнее, по телевизору показывают — там какой-то придурок
по встречной полосе едет!!!
— Ты не поверишь, их здесь сотни!!!
Здравствуйте, IB, Вы писали:
T>>За надом (понимать буквально) IB>То есть, очень хочется, но объяснить не можешь? )
Да чего там объяснять-то? Влом Фаулера переписывать.
T>> Зачем отказываться от этого в domain model я не понимаю. IB>Потому что там это не нужно и даже вредно.
Здравствуйте, IB, Вы писали:
T>>Потому что реляционные операторы это — объединение, пересечение, разность, произведение, сокращение, проекция, соединение, деление. Другие в реляционную алгебру не входят. IB>Я тебе больше скажу, SQL вообще мало отношения к реляционной алгебре имеет. Только работают все с SQL-ем, а не с реляцонной алгеброй в вакууме. IB>Ты что сказать-то хотел?
Меня несколько смутило, что insert-ы, да update-ы относят к реляционным операторам. Теперь ясно что имелось в виду другое. Проехали.
T>>Я считаю этот вопрос стоит разделить на 2: T>>1) ER vs ObjectModel: мой выбор однозначно в пользу ObjectModel. Потому что она банально предоставляет больше возможностей. IB>Если бы это было так, то весь мир уже давно бы сидел на ООБД. Правда заключается в том, что большинство возможностей ОО подхода при работе с данными оказываются либо бесполезными, либо вообще вредными.
Раз уж мы аппелируем к большинству, то это большинство какраз-таки пользуется разными Hibernate-ами вовсю.
T>> Кроме того, er может быть смоделирована через object model, обратное — неверно. IB>Приведи мне пример объектов, которые нельзя было бы смоделировать, через ER?
Наследование. Отношения многие ко многим. Методы. Интерфейсы.
T>>2) SQL DML vs unit of work: unit of work в большинстве случаев удобнее и предпочтительнее. IB>Это в каких, например?
См. Фаулера. Перепечатывать цитаты я не буду.
T>> Единственный его недостаток — это когда нужно массово обновить большое количество объектов. IB>Если под "массово обновить большое количество объектов" понимается, что объектов больше одного, то согласен.
Большое количество однородных объектов. В качества примера можно привести например миграцию данных с одной схемы базы на другую.
IB>Проблема только в том, что таких случаев в реальной жизни подавляющее большинство, отсюда делаем совершенно закономерный вывод, что UoW конструкция бесполезная.
В моей "реальной жизни" такого рода массовое обновление встречается не так уж и часто, так что пусть живет.
T>>>Мне доводилось работать с корпоративными приложениями, в том числе с достаточно крупными (Axapta). IB>>
T>Что тебя так развеселило? Расскажи, вместе посмеемся.
присоединяюсь
Вообще похоже, что спор возник на пустом месте, точнее в разных координатах.
Крупные системы — это действительно Крупные системы.
Не AXAPTA, не 1С, не sharepoint.
Тебе не известны проблемы масштабных систем, поэтому спорить нет смысла.
T>>>2) SQL DML vs unit of work: unit of work в большинстве случаев удобнее и предпочтительнее. IB>>Это в каких, например?
T>См. Фаулера. Перепечатывать цитаты я не буду.
Здравствуйте, VGn, Вы писали:
T>>См. Фаулера. Перепечатывать цитаты я не буду.
VGn>Ещё что-нибудь читал?
Думаю основное из того, что издавалось на русском языке + многое из того что издавалось на английском я читал.
Если интересуют какие-то конкретные книги, готов ответить.
Здравствуйте, VGn, Вы писали:
VGn> Вообще похоже, что спор возник на пустом месте, точнее в разных координатах. VGn> Крупные системы — это действительно Крупные системы. VGn> Не AXAPTA, не 1С, не sharepoint. VGn> Тебе не известны проблемы масштабных систем, поэтому спорить нет смысла.
А почему Axapta не является крупной системой?
Я знаю что в России есть предприятия на которых она используется на наскольких тысячах рабочих мест + бизнес логика там весьма не простая.
Ты считаешь это не крупная система?
T>>>В варианте с UoW на время операции будет наложена shared блокировка и только на время submit-а — более тяжелая exclusive. S>>А ничего, что в случае отката транзакции значение поля А, прочитанное кем-то во время "удержания shared блокировки", будет потеряно?
T>Я не совсем интонацию понял. Для меня вопрос звучит столь же нелепо, как и спрашивать — "а ничего, что при откате транзакции изменения потеряются".
Дело не в интонации. см. ниже. S>>Если ничего, то можно разбить транзакцию на две, и не удерживать эксклюзивную блокировку во время тяжелых вычислений. T>Нельзя, целостность будет потеряна.
T>Не улавливаю ход рассуждения, распиши подробнее.
Поясняю еще раз: в промежутке между первым апдейтом и вторым может вклиниться чтение из посторонней транзакции. Удержание эксклюзивной блокировки гарантирует отсутствие этого вклиненного чтение. Предлагаемый тобой вариант с наложением shared lock чреват фантомным чтением. Ты сам только что сказал, что нарушение целостности недопустимо. ЧТД.
T>Задание на дом. Перечитай свое же сообщение еще раз.
А вот хамить не надо.
T>Вручную педалить тяжело если вы остаетесь в рамках trabsaction script-а. Переходите на ооп подход и волосы становятся густыми и блестящими
ООП подход нужно применять с умом. Речь не о transaction script, а о современных техниках подготовки запросов.
T>Пока у них это не очень хорошо получается. Те средства декомпозиции запросов, что есть в SQL-е и в базах данных (WITH, view, функции) просто смешны и не выдерживают никакой критики.
Я еще раз напомню, что речь идет как раз о более современных средствах декомпозиции запроса, чем with. К тому же вы зря так пренебрежительно относитесь к view и функциям — они могут серьезно помочь, если их правильно готовить.
T>Как бороться со ложностью? Как это тестировать? и так далее.
Еще раз поясняю: единственный способ бороться со сложностью, придуманный прогрессивным человечеством — это декомпозиция. Да, возможности по декомпозиции, заложенные в SQL, не слишком мощны. Но вот Linq предлагает более совершенные средства, на которые я кратко намекнул.
T>ООП дает на эти вопросы более менее внятный ответ.
Мне не нравится вариант ответа, который обеспечивает плохую изоляцию транзакций и низкое быстродействие. Я перфекционист, мне нужна комната с видом на море.
T>Не пойму, что тебе запрещает использовать танзакции-то? И полчишь "целостность, которая доступна в старинном SQL забесплатно".
Поясняю на пальцах: понятие транзакционной целостности, в частности включает в себя отслеживание того факта, что прочитанные в начале транзакции данные остаются актуальными и в ее конце. В частности, если я делаю модификацию позиций заказа, я должен вначале проверить, что сам заказ еще не отгружен. SQL достигает этого путем наложения блокировок даже при выполнении селект стейтмента. Unit of Work никак не отслеживает чтения, сделанные в процессе выполнения транзакции.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
T>>Задание на дом. Перечитай свое же сообщение еще раз. S>А вот хамить не надо.
А я и не хамлю.
Пункт 4 не выполнен.
T>>Как бороться со ложностью? Как это тестировать? и так далее. S>Еще раз поясняю: единственный способ бороться со сложностью, придуманный прогрессивным человечеством — это декомпозиция. Да, возможности по декомпозиции, заложенные в SQL, не слишком мощны. Но вот Linq предлагает более совершенные средства, на которые я кратко намекнул.
Кстати, еще одно вспомнилось, что непонятно как поддеживать в Linq-е — рекурсивные запросы.
T>>ООП дает на эти вопросы более менее внятный ответ. S>Мне не нравится вариант ответа, который обеспечивает плохую изоляцию транзакций и низкое быстродействие. Я перфекционист, мне нужна комната с видом на море.
Дерзайте, я не против.
Если что получится — хорошо, значит примем на вооружение еще один прием.
Не получится — тоже хорошо, значит я был прав.
T>>Не пойму, что тебе запрещает использовать танзакции-то? И полчишь "целостность, которая доступна в старинном SQL забесплатно". S>Поясняю на пальцах: понятие транзакционной целостности, в частности включает в себя отслеживание того факта, что прочитанные в начале транзакции данные остаются актуальными и в ее конце. В частности, если я делаю модификацию позиций заказа, я должен вначале проверить, что сам заказ еще не отгружен. SQL достигает этого путем наложения блокировок даже при выполнении селект стейтмента. Unit of Work никак не отслеживает чтения, сделанные в процессе выполнения транзакции.
Опять нифига не понятно. Чтение в Unit of Work в конечном итоге — это тот же SELECT. Тут или ты чего не договоариваешь, или .. на этом моя мысль заканчивается.
VGn>>Ещё что-нибудь читал?
T>Думаю основное из того, что издавалось на русском языке + многое из того что издавалось на английском я читал. T>Если интересуют какие-то конкретные книги, готов ответить.
На протяжении всего обсуждения было несколько твоих отсылок только к одной (как я понял) книге Фаулера. Причём той, ценность которой мне лично не очевидна.
Я имею в виду Patterns of Enterprise Application Architecture, содержание которой в общем нареканий не вызывает. Сомнительно только слово Enterprise.
T>А почему Axapta не является крупной системой? T>Я знаю что в России есть предприятия на которых она используется на наскольких тысячах рабочих мест + бизнес логика там весьма не простая. T>Ты считаешь это не крупная система?
С точки зрения структуры предприятия и масштабов бизнеса, Axapta лучше всего подходит компаниям:
* численностью до 10 000 сотрудников;
* с оборотом — от 10 до 800 млн. долларов;
* с потребностью в автоматизации от 25 до 500 рабочих мест одновременных пользователей (на практике существуют инсталляции до 1000 рабочих мест, тестовые инсталляции до 3600);
* имеющим специфические и сложные бизнес процессы;
* предприятиям с распределенной структурой, холдингам, дистрибьюторским компаниям, производственным предприятиям, компаниям, работающим в сфере услуг и др.
Я работал над системой, автоматизирующей 30 000 рабочих мест. Сейчас — 3000-10000 (в зависимости от филлиала, коих около десятка).
Всё познаётся в сравнении.
Здравствуйте, VGn, Вы писали:
T>>А почему Axapta не является крупной системой? T>>Я знаю что в России есть предприятия на которых она используется на наскольких тысячах рабочих мест + бизнес логика там весьма не простая. T>>Ты считаешь это не крупная система?
VGn>
VGn>С точки зрения структуры предприятия и масштабов бизнеса, Axapta лучше всего подходит компаниям:
VGn> * численностью до 10 000 сотрудников;
VGn> * с оборотом — от 10 до 800 млн. долларов;
VGn> * с потребностью в автоматизации от 25 до 500 рабочих мест одновременных пользователей (на практике существуют инсталляции до 1000 рабочих мест, тестовые инсталляции до 3600);
VGn> * имеющим специфические и сложные бизнес процессы;
VGn> * предприятиям с распределенной структурой, холдингам, дистрибьюторским компаниям, производственным предприятиям, компаниям, работающим в сфере услуг и др.
Тем не менее есть преценденты внедрения на несколько тысяч мест. Внедрял Корус-Консалтинг. Какой-то трубный завод на урале, кажется.
VGn>Я работал над системой, автоматизирующей 30 000 рабочих мест. Сейчас — 3000-10000 (в зависимости от филлиала, коих около десятка).
Само количество абсолютно ничего не говорит. Сложности бизнес-логики тоже важна.
Здравствуйте, VGn, Вы писали:
VGn>На протяжении всего обсуждения было несколько твоих отсылок только к одной (как я понял) книге Фаулера. Причём той, ценность которой мне лично не очевидна. VGn>Я имею в виду Patterns of Enterprise Application Architecture, содержание которой в общем нареканий не вызывает. Сомнительно только слово Enterprise.
Я не знаю аналогов Фаулеру, в котором бы в такой же степени покрывались бы вопросы разработки корпоративных приложений.
Если есть что-то подобное на слуху, было бы интересно узнать.
T>Тем не менее есть преценденты внедрения на несколько тысяч мест. Внедрял Корус-Консалтинг. Какой-то трубный завод на урале, кажется.
1С тоже пытаются внедрять в больших корпорациях. И что? Она после этого становится масштабируемой?
VGn>>Я работал над системой, автоматизирующей 30 000 рабочих мест. Сейчас — 3000-10000 (в зависимости от филлиала, коих около десятка).
T>Само количество абсолютно ничего не говорит. Сложности бизнес-логики тоже важна.
T>Я не знаю аналогов Фаулеру, в котором бы в такой же степени покрывались бы вопросы разработки корпоративных приложений. T>Если есть что-то подобное на слуху, было бы интересно узнать.
Как-то даже сложно с аналогами. Потому что как раз о корпоративных приложениях я там ничего не нашёл.
Трудно назвать корпоративным приложение, в котором смешиваются воедино уровень доступа к данным, Domain уровень, уровень сервисной бизнес-логики и ещё всего помаленьку.
А для ваших настольных систем — это вполне себе как раз. Только Enterprise тут ни при чём.
Здравствуйте, Tissot, Вы писали:
T>Здравствуйте, gandjustas, Вы писали:
G>>>>Еще раз. Не путайте суть и форму. Форма будет одинаковая: классы, объекты, интерфесы, наследование. При ООП подходе у вас будет императивный код работы с объектами. При ER — декларативный код работы с сущностями. T>>>Ок. Я понял, под er вы подразумеваете не er-модель. Проехали. G>>А что вы подразумеваете под ER моделью в программе?
T>Под ER-моделью я, как ни странно, понимаю ER-модель
Круто. А как это использовать в программе?
Вы вообще представляете то о чем спор ведете?
T>Ясно. Я использовал такой подход в простых сценариях, когда при определенных условиях нужно было применять дополнительное условие. T>Но такой подход не всегда применим. В частности, в проекте на котором я сейчас работаю настройки безопасноти (привелегии) хранятся во внешней базе.
Ну это надуманные проблемы. Всегда есть view, linked servers и прочее. Только далеко не все могут нормальную интеграцию баз сдеать на уровне БД. Гораздо проще сделать в коде приложения, а потом рассказывать что это "непрстой сценарий" и прочее.
T>>>То есть каждому пользователю давать свой логин в базе? Ты в курсе, что так делать не рекомендуют? G>>Нет, есть таблица, хранящая логины и другие сведения о пользователях. В логах можно ссылкаться на эту таблицу.
T>А как определить текущего пользователя?
Разве вы в программе в кажом месте не можете определить текущего пользователя (логин\id\что_нибудь_еще)?
T>>>Такие тесты работать будут часами. Главное требование к юнит-тесту — это то, что он работает оч. быстро. Станет работать медленно, никто их запускать не будет. На себе проверено. G>>Вам не потребуется эти тесты запускать в совокупноти с unit-тестами приложения. Аудит в БД полностью ортогонален бизнес-логике в коде приложения.
T>Почему не понадибится? Как иначе проверишь, что определенные действия отражаются в аудит-логе?
Тесты базы будут запускаться при разработке БД. С тестированием кода приложения они не связаны. Пусть build-система на сервере гоняет такие тесты хоть каждые 5 минут, каждому разработчику делать тоже самое необязательно.
G>>>>Вы не поняли. Действительно можно будет выполнить ВСЕ запросы в одной транзакции. При использовании ОРМ придется сделать выборку в одной транзакции, а потом коммит в другой. T>>>Это еще почему? G>>Потому что реализация такая. Linq2SQL и EF так работают. T>Открывай TransactionScope и будет одна транзакция. Или я опять что-то не понимаю?
См ниже.
G>>>>Можно явно объявить TransactionScope, но тогда её придется явно завершить после вызова SaveChanges. T>>>Это сложно? G>>Это сложнее чем ОДИН раз явно обявить транзакцию при использовании запросов. T>Все равно не вкуриваю. Код с TransactionScope — правтически один-в-один с приводимым тобой кодом. В чем отличие-то?
С запросами, теоретически
using (context.Batch())
{
var q = from ...
update ...
delete ...
}//Непосредственное выполнение начинается здесь
Без запросов, как сейчас
using(var ts = new TransactionScope())
{
var q = from ...
foreach(var e in q) //Материализация запросва, блокировка удерживается
{
//Какие-то действия
}
//Две строчки надо еще не перепутать
context.SaveChanges(); //Сохранение изменений
ts.Commit();
}
Во втором блоке 2 строчки нужно выполнить.
G>>>>При материализации последнего запроса вылетит ошибка и транзакция будет откачена если остатки ушли в минус, а кастомер не VIP.
T>>>То есть сначала мы пишем в базу, а потом валидируем? Оригинально G>>При таком подходе ВСЯ работа с данными происходит в БД, это нормально.
T>БД — это всегда узкое место. Если есть возможность делать проверки в бизнесе, они болжны быть сделаны в бизнесе. Неужели эти банальности нужно повторять?
Эти "банальности" еще нужно доказать.
Сама по себе БД — не узкое место, узкое мето — передача данных от БД к приложению и назад. Именно эту передачу и предлагают сократить.
Кстати при работе с embedded базами данных "правила игры" меняются.
Содержание бизнес-логики в коде приложения выгодно не с точки зрения перформанса, а с точки зрения стоимости поддрежки. Но при работе с запросами логика остается в коде приложения, меняется только место исполнения.
БД кстати очень хорошо умеет параллелить выполнение запросов, использует индексы, чтобы даже не забивать память данными, не используемыми в запросах, умеет кешировать часто используемые данные и гораздо лучше управляет блокировками и конкуретным доступом, чем любая реализация в коде приложения.
Вы обработку бизнес-логики распараллеливаете?
T>>>Это точно ты говорил, что материализация плохо отражается на перформансе? G>>Это так и есть. T>И как это сочетается с тем, что валидацию ты возлагаешь на базу, когда ее можно сделать в бизнесе, что дешевле?
Что значит "дешевле"?
При правильном подходе возлагать работу с данными на БД даст огромный прирос производительности.
Сравните например например выполнение запроса типа "увеличить скидку всем VIP кастомерам скиду на все заказы прошлого года на 3 процента" с выполнением тогоже самого с помощью ORM.
T>>>P.S. На самом деле то, что вы описываете, до боли напоминает transaction script как он назван у Фаулера. Единственное отличие, которое я вижу — это его типизированность. В той же книжке описывается почему с ростом сложности приложения с transaction script-ом становится сложно жить. Рекомендую глянуть, если еще не смотрели. G>>Я уже форуме "архитектура" про фаулера отписал. Повторюсь здесь. G>>Концептуальная разница между transaction script и dimain model состоит в том как вы хотите вызывать методы бизнес-логики G>>Так G>>
G>>entity.Operation(params)
G>>
G>>или так G>>
G>>service.Operation(entity, params)
G>>
G>>Второй подход гораздо лучше по многим причинам.
T>Сервисы не отрицают domain model, а дополняют ее. T>Развитая доменная модель позволяет защитить целостность данных в доменной модели и сделать код более читаемым, близким к предметной области.
Звучит как молитва какая-то.
G>>А фаулер какю-то неправильную траву курит.
T>Да они там все такие :
Да вот не все. App Arch Guide 2.0 почитайте.
Здравствуйте, Tissot, Вы писали:
T>>>Почему вариант с update/insert будет иметь меньшее кол-во блокировок? IB>>Он будет держать их меньшее время и блокировки будут поддаваться большему контролю.
T>Я же привел пример: T>1. делаем update 1 поля T>2. долго что-то считаем T>3. делаем следующий update
T>Не мог бы ты оставаясь в рамках этого примера описать, откуда возникнет "меньшее время" и "больший контроль"?
Если расчеты в п2 не зависят от апдейта в п1, то сначала выполняем расчеты (не ставим эксклюзивные блокировки), потом формируем 2 апдейта и выполняем их в БД.
Если расчеты в п2 зависят от апдейта в п1, то выделяем независимую часть расчетов из п2 и выполняем, потом выполняем апдейт, зависимую от апдейта часть расчетов (гораздо быстрее), мерджим с независимой, выполняем второй апдейт.
Здравствуйте, gandjustas, Вы писали:
T>>Под ER-моделью я, как ни странно, понимаю ER-модель G>Круто. А как это использовать в программе?
Собственно ER модель мапится в объектную очень легко. Практически один в один.
G>Вы вообще представляете то о чем спор ведете?
Пока что я пытаюсь выяснить что вы имели в виду под ER-моделью. Пока что выяснилось, что ваша ER-модель != ER-модели как ее представлет википедия.
T>>Ясно. Я использовал такой подход в простых сценариях, когда при определенных условиях нужно было применять дополнительное условие. T>>Но такой подход не всегда применим. В частности, в проекте на котором я сейчас работаю настройки безопасноти (привелегии) хранятся во внешней базе. G>Ну это надуманные проблемы. Всегда есть view, linked servers и прочее. Только далеко не все могут нормальную интеграцию баз сдеать на уровне БД. Гораздо проще сделать в коде приложения, а потом рассказывать что это "непрстой сценарий" и прочее.
И как view и linked servers ты собрался вписать в LINQ-подход?
T>>>>То есть каждому пользователю давать свой логин в базе? Ты в курсе, что так делать не рекомендуют? G>>>Нет, есть таблица, хранящая логины и другие сведения о пользователях. В логах можно ссылкаться на эту таблицу.
T>>А как определить текущего пользователя? G>Разве вы в программе в кажом месте не можете определить текущего пользователя (логин\id\что_нибудь_еще)?
В программе — могу. А вот как это сделать это в триггере для меня не ясно. Если вы знаете, буду благодарен если просвятите.
T>>Почему не понадибится? Как иначе проверишь, что определенные действия отражаются в аудит-логе? G>Тесты базы будут запускаться при разработке БД. С тестированием кода приложения они не связаны. Пусть build-система на сервере гоняет такие тесты хоть каждые 5 минут, каждому разработчику делать тоже самое необязательно.
Э, нет, так не пойдет. Код не должен выкладываться в репозитарий если он не прошел тесты.
G>>>>>Вы не поняли. Действительно можно будет выполнить ВСЕ запросы в одной транзакции. При использовании ОРМ придется сделать выборку в одной транзакции, а потом коммит в другой. T>>>>Это еще почему? G>>>Потому что реализация такая. Linq2SQL и EF так работают. T>>Открывай TransactionScope и будет одна транзакция. Или я опять что-то не понимаю? G>См ниже.
G>>>>>Можно явно объявить TransactionScope, но тогда её придется явно завершить после вызова SaveChanges. T>>>>Это сложно? G>>>Это сложнее чем ОДИН раз явно обявить транзакцию при использовании запросов. T>>Все равно не вкуриваю. Код с TransactionScope — правтически один-в-один с приводимым тобой кодом. В чем отличие-то?
G>С запросами, теоретически G>
G>using (context.Batch())
G>{
G> var q = from ...
G> update ...
G> delete ...
G>}//Непосредственное выполнение начинается здесь
G>
G>Без запросов, как сейчас G>
G>using(var ts = new TransactionScope())
G>{
G> var q = from ...
G> foreach(var e in q) //Материализация запросва, блокировка удерживается
G> {
G> //Какие-то действия
G> }
G> //Две строчки надо еще не перепутать
G> context.SaveChanges(); //Сохранение изменений
G> ts.Commit();
G>}
G>
G>Во втором блоке 2 строчки нужно выполнить.
Блин, а я-то думал тут действительно какие-то страшные косяки, а тут оказывается аж 2 строчки.
Оберни это в хелперный класс, если тебя так беспокоит количество эти лишние строчки и будет все так же как и в твоем коде.
T>>БД — это всегда узкое место. Если есть возможность делать проверки в бизнесе, они болжны быть сделаны в бизнесе. Неужели эти банальности нужно повторять? G>Эти "банальности" еще нужно доказать. G>Сама по себе БД — не узкое место, узкое мето — передача данных от БД к приложению и назад. Именно эту передачу и предлагают сократить.
Нет, ты не предлагаешь сократить передечу в базу. В твоем сценарии данные сначала пишутся в базу, а потом валидируются. То есть даже невалидные данные ты передаешь. И где тут сокращение?
G>Содержание бизнес-логики в коде приложения выгодно не с точки зрения перформанса, а с точки зрения стоимости поддрежки. Но при работе с запросами логика остается в коде приложения, меняется только место исполнения. G>БД кстати очень хорошо умеет параллелить выполнение запросов, использует индексы, чтобы даже не забивать память данными, не используемыми в запросах, умеет кешировать часто используемые данные и гораздо лучше управляет блокировками и конкуретным доступом, чем любая реализация в коде приложения.
А где я предлагал кэшировать/управлять блокировками/управлять конкурентным доступом в приложении?
G>Вы обработку бизнес-логики распараллеливаете?
В каком-то смысле да, есть некий самописный типа-воркфлоу. Но он к работе с базой не относится.
G>>>Это так и есть. T>>И как это сочетается с тем, что валидацию ты возлагаешь на базу, когда ее можно сделать в бизнесе, что дешевле? G>Что значит "дешевле"?
Быстрее, будет потреблять меньше ресурсов,
G>При правильном подходе возлагать работу с данными на БД даст огромный прирос производительности.
Не надо растекаться мыслью по древу. Как в предложенном тобой сценарии использования валидации в базе получится большая производительность?
G>Сравните например например выполнение запроса типа "увеличить скидку всем VIP кастомерам скиду на все заказы прошлого года на 3 процента" с выполнением тогоже самого с помощью ORM.
Про массовые update-ы я писал. Тут все ясно, согласен на все 100.
T>>Сервисы не отрицают domain model, а дополняют ее. T>>Развитая доменная модель позволяет защитить целостность данных в доменной модели и сделать код более читаемым, близким к предметной области.
G>Звучит как молитва какая-то.
Воздастся каждому по вере его.
G>>>А фаулер какю-то неправильную траву курит. T>>Да они там все такие : G>Да вот не все. App Arch Guide 2.0 почитайте.
Спасибо, почитаю.
Читал предыдущую версию. Неужели что-то коренным образом изменилось?
Здравствуйте, VGn, Вы писали:
T>>Тем не менее есть преценденты внедрения на несколько тысяч мест. Внедрял Корус-Консалтинг. Какой-то трубный завод на урале, кажется.
VGn>1С тоже пытаются внедрять в больших корпорациях. И что? Она после этого становится масштабируемой?
Я не знаю как сейчас, но на тот момент (где-то 5 лет назад) 1С на такое кол-во пользователей даже и не пытались внедрить.
VGn>>>Я работал над системой, автоматизирующей 30 000 рабочих мест. Сейчас — 3000-10000 (в зависимости от филлиала, коих около десятка).
T>>Само количество абсолютно ничего не говорит. Сложности бизнес-логики тоже важна.
VGn>А вот на этом я и сам хотел сделать упор
А вы прямым текстом говорите, что хотите сказать.
Если вы считаете, что Axapta — простой продукт, то хотелось бы мне посмотреть на то, что является по вашему мнению сложным.
Здравствуйте, gandjustas, Вы писали:
T>>Не мог бы ты оставаясь в рамках этого примера описать, откуда возникнет "меньшее время" и "больший контроль"?
G>Если расчеты в п2 не зависят от апдейта в п1, то сначала выполняем расчеты (не ставим эксклюзивные блокировки), потом формируем 2 апдейта и выполняем их в БД. G>Если расчеты в п2 зависят от апдейта в п1, то выделяем независимую часть расчетов из п2 и выполняем, потом выполняем апдейт, зависимую от апдейта часть расчетов (гораздо быстрее), мерджим с независимой, выполняем второй апдейт.
А можно не изменять условия задачи?
А то при таком подходе и я теорему Ферма на коленке за минут докажу.