Se due aggregati stanno ascoltando lo stesso evento; quindi l'evento verrà archiviato in un archivio eventi due volte, una volta per ogni aggregato.
class ItemLoaded implements Event {
LocationId location;
VehicleId vehicle;
Amount amount;
Date loadDate;
}
class Location implements Aggregate {
Amount itemAmount;
void updateFrom(ItemLoaded event) {
this.itemAmount.subtract(event.amount);
}
}
class Vehicle implements Aggregate {
Amount itemAmount;
void updateFrom(ItemLoaded event) {
this.itemAmount.add(event.amount);
}
}
Ad esempio ci saranno voci dell'evento ItemLoaded
nel negozio una volta per Location
e una volta per Vehicle
, nel caso precedente.
Questo è quanto ci si aspetta, come si può vedere dai due esempi di giocattoli qui sotto, che potresti aver già visto se hai letto sul sourcing di eventi:
In un esempio :
_current = new Dictionary<Guid, List<EventDescriptor>>();
In altro esempio :
CREATE TABLE EventWrappers(
EventId uniqueidentifier NOT NULL,
StreamId nvarchar(50) COLLATE Latin1_General_CI_AS NOT NULL,
Sequence bigint NOT NULL,
TimeStamp datetime NOT NULL,
EventType nvarchar(100) COLLATE Latin1_General_CI_AS NOT NULL,
Body nvarchar](max) COLLATE Latin1_General_CI_AS NOT NULL,
I sistemi di produzione non sono probabilmente così diversi. In framework axon l'evento è memorizzato in una tabella come di seguito, se si sceglie l'implementazione JPA o JDBC dell'archivio degli eventi:
create table DomainEventEntry (
-- .....
primary key (aggregateIdentifier, sequenceNumber, type)
);
Il campo type
sopra è una stringa utilizzata per differenziare diversi tipi di aggregati.
Dato che apparentemente gli eventi potrebbero persistere più volte, se voglio ricreare una vista da zero o aggiungere un nuovo modello di vista, come posso riprodurre gli eventi.
Se torniamo all'esempio precedente, prendiamo in considerazione un modello di visualizzazione come questo:
class ItemsLoadedByYearProjection {
@Subscribe
void update(ItemLoaded event) {
ItemsLoadedByYear row = getRowForYear(event.loadDate.year);
row.itemAmount.add(itemAmount);
}
}
class ItemsLoadedByYear {
int year;
Amount itemAmount;
}
Non solo gli importi verranno conteggiati due volte, se ripeto gli eventi in modo ingenuo; se aggiungo un nuovo aggregato in futuro, alcuni eventi verranno conteggiati due volte, mentre altri verranno conteggiati tre volte.
Come posso evitare che una proiezione / denormalizzatore esegua il doppio conteggio degli eventi che sono stati salvati nell'archivio eventi più volte?