Also, was vermisse ich?
Eine Vermutung anstellen.
Das erste, was Ihnen möglicherweise fehlt, ist, dass Sie nur die Ereignisse für den Status neu laden müssen, den Sie neu erstellen. Wenn Sie Ihre Transaktionsgrenzen sauber modellieren können, kann jedes Objekt Ereignisse mit seiner eigenen ID ausschreiben und dann nur diese Ereignisse zurücklesen. Bei Verwendung einer relationalen Datenbank für die Ereignisspeicherung würde eine indizierte ID-Spalte vorhanden sein, um diese Abfrage zu beschleunigen. Bei Verwendung von EventStore hätte jedes Objekt einen eigenen Stream.
In Ihrem Modell ist einige Sorgfalt erforderlich, um dies sauber zu tun, da Sie sicherstellen möchten, dass Sie nur ein einzelnes Objekt in jeder Transaktion ändern, und daher darauf achten müssen, dass Sie jede Invariante, die Sie versuchen, korrekt isolieren erzwingen.
In Fällen, in denen dies nicht schnell genug ist, haben Sie immer noch die Möglichkeit, Schnappschüsse Ihres Status zu erstellen (Memoization) und diese im "traditionellen Speicher" beizubehalten. Jeder Snapshot wird mit der Sequenznummer des letzten Ereignisses versehen, das zum Erstellen des Snapshots verwendet wurde. Beim erneuten Laden greift das Repository zuerst auf diesen Snapshot zu und wendet dann neuere Ereignisse darauf an. (Dies impliziert einen vernünftigen Weg, um die neueren Schnappschüsse zu erfassen. Entweder sind die Ereignisse auch mit der Sequenznummer versehen, oder Sie haben eine effiziente Möglichkeit, den Ereignisstrom rückwärts zu lesen, bis Sie zu Ihrem Ausgangspunkt gelangen.)
Es gibt immer noch einen Vorteil gegenüber dem üblichen Ansatz, da Ihre Schnappschüsse parallel zu Ihren Schreibvorgängen erstellt werden können, anstatt mit ihnen zusammengeführt zu werden: Sie fügen einfach einen Ereignis-Listener in einen anderen Thread / Prozess ein und lassen ihn fröhlich mitschreiben zum Snapshot-Speicher nach einem beliebigen Zeitplan. Schließlich muss der Schnappschuss nicht besonders aktuell sein - gerade oft genug, damit die Arbeit der erneuten Anwendung der neueren Ereignisse Ihre SLA nicht beeinträchtigt.
(Snapshotting erschwert die Migration. Änderungen an der Serialisierung des Modells machen den Snapshot-Cache ungültig. Natürlich können Sie Snapshots mithilfe der neuen Serialisierung im Rahmen der Migration neu erstellen und dann "aufholen", wenn die Änderungen live gehen.)
Wird das Wiederherstellen des Status aus dem Ereignisstrom überhaupt häufig durchgeführt?
Ja, so ist es. In CQRS-Beispielen wird normalerweise gezeigt, dass die Anwendungsschicht, nachdem sichergestellt wurde, dass der übermittelte Befehl korrekt erstellt wurde, die Domänenschicht das Domänenobjekt aus einem Repository lädt, wobei das Laden ein Standardkonstruktor ist, gefolgt von einer Wiedergabe des Ereignisstroms (oder gleichwertig ein Anruf bei einer Fabrik mit einer Liste von Ereignissen).
Zwei weitere widersprüchliche Gedanken.
- Hinter der Repository-Schnittstelle befindet sich möglicherweise ein Cache
- Die Cache-Ungültigmachung ist eines der beiden schwierigen Probleme.