Come gestire gli eventi duplicati durante la riproduzione dell'archivio degli eventi?

1

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?

    
posta abuzittin gillifirca 06.03.2015 - 16:17
fonte

1 risposta

5

If two aggregates are listening to the same event; then the event will be stored in an event store twice, once for each aggregate.

Lo scriverei in modo diverso. Se due aggregati stanno ascoltando lo stesso evento, le rappresentazioni di quell'evento verranno visualizzate nella cronologia di ciascuna.

Non memorizzeranno lo stesso evento e l'evento che archiviano non sarà l'evento a cui stanno rispondendo.

Gli aggregati memorizzeranno eventi che descrivono le modifiche al loro stato, non le modifiche da specificare altrove nel dominio a cui stanno rispondendo.

Quando hai ragione, ricreare gli aggregati è facile: ogni aggregato carica la sua storia. Non c'è un "doppio conteggio" di cui preoccuparsi, perché ogni evento nella cronologia rappresenta una modifica a un aggregato, quindi sono tutte cose diverse.

    
risposta data 19.01.2016 - 19:31
fonte

Leggi altre domande sui tag