2017-01-28 24 views
4

В чем разница между «корневым агрегатом» и «агрегатом» в хранилище событий?хранилище корневого хранилища событий против агрегата

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

Кроме того, я видел сводные таблицы с номерами версий, которые я сбиваю с толку в предположении, что они являются, по существу, идентификаторами групп/контейнеров/агрегатов, представляющими совокупность событий.

+0

Вы говорите об Агрегате и Агрегате корневых шаблонов DDD? Они имеют мало общего с Event Sourcing. –

+0

Да, я читал, что сами модели DDD не связаны с источником событий, но Грег Янг часто обсуждает и документирует эти два вместе. Таблица (ы), о которой идет речь, имеет отношение внешних ключей к таблице событий в представленных примерах. http://danielwhittaker.me/2014/11/15/aggregate-root-cqrs-event-sourcing/ https://cqrs.wordpress.com/documents/building-event-storage/ – webish

ответ

5

Таким образом, мы договорились, что вы пытаетесь создать потоки событий в массивах DDD Aggregate Root и Aggregate.

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

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

Поэтому, если у вас есть сводный корень MyNamespace.Order, который имеет несколько объектов или объектов дочернего значения MyNamespace.OrderLine, все операции над линиями выполняются путем доступа к агрегированным корневым методам, и все события записываются в один поток, поэтому для заказа с идентификатором 123 было бы:

поток: MyName

  • space.Order-123
  • OrderPlaced
  • OrderDeliveryAddressSet
  • OrderLineAdded
  • OrderLineAdded
  • OrderLineRemoved
  • OrderConfirmed
  • OrderETASet
  • OrderPaid
  • OrderDispatched
  • OrderDelivered

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

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

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

Относительно "таблиц" Я не совсем уверен, что вы имеете в виду. Конечно, вы можете смоделировать хранилище событий в таблицах, и при этом есть разные стратегии. Чаще всего вам не нужно использовать специализированный магазин событий, например this one.

+0

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

+2

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

2

В книге и терминах DDD конкретно не указаны источники событий (это еще не A Thing).

SE Radio podcast 226 with Eric Evans охватывает это немного.

An агрегатный представляет собой набор связанных сущностей и значение объектов, которые, в совокупности, модель одна вещь (или соответствующий набор вещей), которые должны оставаться внутренне непротиворечивой

The Совокупный Root может быть корневым объектом, который просматривает совокупность «через» (например, объект-фактура, где у вас есть это, и отдельный набор строк заказа).

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

В книге «Реализация DDD» приложение «Инициирование функциональных событий» отделяет это хорошо. IIRC. Я склонен ссылаться на эту вещь (совокупность связанных событий Агрегата для целей создания) как «сложенное состояние», (а также выделить эволюцию этого кратное государства от фактического принятия решений)


Проекция (в DDD-CQRS-ES жаргоне) относится к абстрактному набору вещей висят события, которые делают соответствующее вещи в ответ на новые события (представляющие собой решения, принятые людьми). Проекция может поддерживать Denormalized View ala your 'summary' (есть не только один). В потоке есть события. Процесс принятия решений сводит эти события к тому, чтобы вывести соответствующий контекст для принятия решения. A проекция может иметь состояние (построенное из хорошо упорядоченного наблюдения соответствующего подмножества событий, относящихся к потоку (или их набору)) - это может быть blob, который хранится в хранилище значений ключей, готовом быть легко спросить. Это может быть общий объем памяти в потоке, который вы создаете, начиная с самого начала. Это может быть аналогичный кеш в памяти, который поддерживается некоторой формой контрольной точки (последнее событие номер один видел), вместе с сериализованной формой того, что суммировало ее как до этой точки. Это может быть много из них. Или в дегенеративных случаях у вас может не быть ничего подключенного.

+0

С CQRS события поиск также есть концепция проекции. Мне кажется, что в то время как существует совокупность, она не может содержать сводку совокупности ??? Например, последнее состояние заказа (все поля) суммируется для всех событий. Это резюме составлено в проекте, где потребители могут его прочитать ...Необходимо задать вопрос как отдельный вопрос. – webish

+0

@webish Да, лучше всего думать об этом как о совершенно отдельной вещи. Отредактировано в чем-то. –