2017-10-12 1 views
1

Nehmen wir an, wir haben ein Aggregat User, das eine UserPortraitImage und eine Contract als PDF-Datei hat. Ich möchte Dateien in einem dedizierten dokumentenbasierten Speicher speichern und nur prozessrelevante Daten im Ereignis speichern (mit einem Link zu den BLOB-Daten).Vermeiden Sie zweiphasige Commits in einer ereignisbezogenen Anwendung, die BLOB-Daten speichert

Aber wie vermeide ich eine zweiphasige Festschreibung, wenn ich die Dateien speichern und das neue Ereignis speichern muss?

Zuerst würde ich die Dokumente und dann das Ereignis speichern; Wenn die erste Transaktion fehlschlägt, spielt der Befehl keine Rolle. Wenn die zweite Transaktion fehlschlägt, ist es auch dann nicht von Bedeutung, wenn wir einige tote Dateien im Speicher generieren, der Befehl schlägt fehl; Wir könnten sogar einen Rollback anwenden. Aber könnte es ein zusätzliches Problem geben?

Die nächste Frage ist, wie Sie das Aggregat und das Ereignis entwerfen. Wenn das Aggregat nur einen Verweis auf den BLOB-Speicher enthält, wie lautet der Prozess, nachdem ein SignUp-Befehl aufgerufen wurde?

SignUpCommand ==> Speichern Sie Dokumente (UserPortraitImage und Contract) ==> Neue User Aggregat mit den Referenzen BLOB-Speicher gegeben und es lagern?

Gibt es ein besseres Design, das das Aggregat davon befreit, zu wissen, dass BLOB-Daten in einem anderen Geschäft gespeichert werden? Und wer ist verantwortlich für das Speichern von BLOB-Daten und das Weiterleiten der Referenz an das Aggregat?

Antwort

2

Klingt, als ob Sie mit etwas ähnlich einem AtomPub media-entry/media-link-entry-Paar arbeiten. Der Blob geht in Ihren Datenspeicher, die Metadaten werden in den Aggregationsverlauf kopiert

Aber wie vermeide ich eine zweiphasige Festschreibung, wenn ich die Dateien speichern und das neue Ereignis speichern muss?

In der Praxis wahrscheinlich nicht.

Das heißt, wenn der Blob-Speicher und der Aggregatspeicher identisch sind, können Sie beide in der gleichen Transaktion aktualisieren. Das koppelt die beiden Shops und fügt Ihrer Speicherauswahl ziemlich starke Einschränkungen hinzu, aber es ist machbar.

Eine andere Möglichkeit besteht darin, dass Sie akzeptieren, dass die zwei Änderungen, die Sie vornehmen, voneinander isoliert sind und daher die beiden Speicher für eine gewisse Zeit nicht konsistent sind.

In diesem zweiten Fall, the saga pattern ist was Sie suchen, und es ist genau das, was Sie beschreiben; Sie pairen die erste Aktion mit einer Kompensationsaktion, die ausgeführt werden soll, wenn die zweite Aktion fehlschlägt. Also "manuelles" Rollback.

Oder nicht - in gewissem Sinne verwendet die Git-Objektdatenbank ein zweiphasiges Commit; Ein Objekt wird in den Objektspeicher kopiert, und dann werden die Bäume aktualisiert, und anschließend wird die Garbage Collection mit commit ... ausgeführt, um die Objekte, die Sie nicht benötigen, zu verwerfen.

Wer ist verantwortlich für das Speichern von BLOB-Daten und das Weiterleiten der Referenz an das Aggregat?

Nun, letztlich ist es ein Infrastrukturproblem; muss Ihr Modell tatsächlich mit dem Dokument interagieren, oder trägt es nur eine claim check, die später eingelöst werden kann?

+0

Wenn ich eine Saga verwende, wo behalte ich die BLOB-Daten in der Zwischenzeit? Wie würde der Prozess aussehen? –

1

Zuerst würde ich die Dokumente und dann das Ereignis speichern; Wenn die erste Transaktion fehlschlägt, spielt es keine Rolle, der Befehl ist fehlgeschlagen. Wenn die zweite Transaktion fehlschlägt, ist es auch dann nicht von Bedeutung, wenn wir im Speicher tot Dateien generiert haben, der Befehl schlägt fehl; Wir könnten sogar eine Rollback anwenden. Aber könnte es ein zusätzliches Problem geben?

Nicht dass ich mir vorstellen kann, abgesehen von ungenutzten Speicherplatz. Das ist, was ich normalerweise tue, wenn ich verteilte Transaktionen vermeiden möchte oder wenn sie in den zwei Arten von Datenspeichern nicht verfügbar sind. Oft ist eine der beiden Operationen weniger wichtig und Sie können es sich leisten, die Operation abzuschließen, auch wenn die Master-Operation später fehlschlägt.

Aufräumen verpatzte Versuche können während der Ausnahmebehandlung, als Out-of-Band-Prozess oder als Teil einer Saga als @VoiceOfUnreason erklärt werden.

SignUpCommand ==> Speichern Sie Dokumente (UserPortraitImage und Vertrag) ==> neuen Benutzer Aggregat erstellen mit den Referenzen BLOB-Speicher gegeben und speichern oder?

Ja. Normalerweise fungiert die Komponente der Anwendungsschicht (Command-Handler in Ihrem Fall) als Koordinator zwischen den verschiedenen Datenspeichern und erhält alles, was sie von einem Geschäft wissen müssen, bevor sie mit dem anderen oder mit der Domäne kommuniziert.

Verwandte Themen