2012-01-31 7 views
0

В настоящее время я использую EventStore J Oliver, и я хочу знать, как я могу проверить, существует ли совокупность при моем вызове (GetById (Guid id))?CQRS/EventStore: как проверить, существует ли совокупность?

Как работает CQRS, следует ли мне запрашивать базу данных для чтения или мне нужно как-то узнать, есть ли соответствующий агрегат в EventStore?

ТИА

JD

ответ

3

Путь EventStore работает на данный момент, вы будете создавать новый поток (совокупный корень), если поток не найден.

Проверить эту линию: https://github.com/joliver/CommonDomain/blob/master/src/proj/CommonDomain.Persistence.EventStore/EventStoreRepository.cs#L53

Он называет этот метод на магазин: https://github.com/joliver/EventStore/blob/master/src/proj/EventStore.Core/OptimisticEventStore.cs#L45

Что вызывает этот конструктор: https://github.com/joliver/EventStore/blob/master/src/proj/EventStore.Core/OptimisticEventStream.cs#L27

Эффект в том, что он будет либо заполнить Ручей с помощью Записывает, что он найден в сохранении, или если ни один не найден, он ничего не сделает и вернет новый поток.

Однако вам не придется задавать себе этот вопрос. Перед отправкой необходимо выполнить проверку. Используйте ваши прочитанные модели для проверки команды перед ее отправкой.

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

Update в ответ на Mauros комментарий:

Вы испытываете проблемы параллелизма. Возможно, вы сможете решить эту проблему, используя метод, используемый в случайно соединенных системах, которые объединяются. Что вы можете сделать, так это сохранить версию Stream в модели чтения, чтобы вы знали, какую ревизию AR вы действовали. Затем, когда команда обрабатывается, вы знаете, действуете ли вы на прежнее состояние AR.

Если ревизия AR выше, чем та, которую приносит команда, вы можете либо отбросить команду как отказ (пессимистический параллелизм), либо попытаться объединить изменения.

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

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

Поиск слияния событий для получения дополнительной информации.

+0

«Команда должна быть проверена перед отправкой» .. что, если прочитанная модель «устарела», потому что другой клиент отправляет событие настойчивость? Я борюсь с этой проблемой –

+0

Я обновил ответ, поскольку он не подходит для поля комментариев, хотя, возможно, лучше было бы использовать отдельный вопрос. –

+0

@ MikaelÖstberg: Большое вам спасибо за информацию. На данный момент я не использовал EventStoreRepository напрямую, так как я все еще изучаю CQRS, и у меня возникали проблемы с CommonDomain. Знаете ли вы о каких-либо проектах/шип-кодах, которые используют CommonDomain? –

1

Я думаю, вы на самом деле ссылаетесь на IRepository.GetById() в проекте JOliver CommonDomain?

Когда вы вызываете GetById с агрегированным корневым идентификатором, который не находится в хранилище событий, репозиторий предоставит вам новый агрегатный объект с .Version == 0 и .Id == Guid.Empty. Я только что создал свой собственный производный репозиторий, который обнаруживает, что состояние и возвращает нулевое значение вместо:

public override TAggregate GetById<TAggregate>(Guid id, int versionToLoad) 
{ 
    var aggregate = base.GetById<TAggregate>(id, versionToLoad); 
    return aggregate.Version > 0 ? aggregate : null; 
} 

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

+0

На самом деле, я думаю, что где-то читал, что Джонатан Оливер думает об изменении поведения по этой проблеме, поскольку довольно странно неявно создавать и возвращать новый поток при запросе существующего. –

+0

@ Эрик: Спасибо за код. Я определенно буду использовать его. В настоящее время я не использую EventStoreRepository, и вместо этого, поскольку я учился, я использовал store.openStream() и т. Д. Напрямую и до сих пор не имею концептуальных снимков. Поэтому, возможно, настало время переключиться на EventStoreRepository. –

+0

@ Эрик: Вы вызываете исключение, если агрегат является нулевым в вашем командном уровне, или было бы лучше создать исключение в GetById <>, если нет агрегата? –

 Смежные вопросы

  • Нет связанных вопросов^_^