Firebase Commit / Rollback für komplexe Schreibvorgänge

8

Ich schreibe eine Finanzanwendung mit Firebase und für eine Empfangsbestätigung müssen auch einige andere Objekte aktualisiert werden. Damit die Daten gültig sind, müssen alle Datenaktualisierungen erfolgreich abgeschlossen werden. Wenn bei einem der Schreibvorgänge ein Fehler auftritt, müssen alle Aktualisierungen zurückgesetzt werden.

Zum Beispiel:

Wenn der Benutzer einen Beleg einreicht, müssen sowohl das Belegobjekt als auch ein Rechnungsobjekt sowie andere Hauptbuchobjekte aktualisiert werden.

Wenn das Update gestartet wurde, aber der Benutzer die Internetverbindung auf halbem Weg verloren hat, sollten alle Änderungen rückgängig gemacht werden.

Was ist der beste Weg, dies in Firebase zu erreichen?

    
Ben Smiley 27.01.2014, 17:23
quelle

1 Antwort

13

Lassen Sie uns zunächst kurz darüber sprechen, warum jemand auf mehreren Datenpfaden Commit / Rollback durchführen möchte ...

Brauchst du das?

Im Allgemeinen brauchen Sie das nicht, wenn:

  • Sie schreiben nicht mit hoher Parallelität (Hunderte von Schreiboperationen pro Minute für den gleichen Datensatz von VERSCHIEDENEN Benutzern)
  • Ihre Abhängigkeiten sind einfach (B hängt von A ab, und C hängt von A ab, aber A hängt nicht von B oder C ab)
  • Ihre Daten können in einem einzigen Pfad zusammengeführt werden

Entwickler sind ein bisschen zu besorgt über verwaiste Datensätze in ihren Daten. Die Wahrscheinlichkeit, dass ein Web-Socket zwischen einem Schreibvorgang und dem anderen versagt, ist wahrscheinlich trivial und irgendwo in der Reihenfolge der Kollisionen zwischen Zeitstempel basierte IDs. Das heißt nicht, dass es unmöglich ist, aber es ist im Allgemeinen eine niedrige Konsequenz, höchst unwahrscheinlich, und sollte nicht Ihre Hauptsorge sein.

Auch Waisen sind extrem einfach mit einem Skript aufzuräumen oder einfach nur ein paar Zeilen Code in die JS-Konsole einzugeben. Also nochmal, Sie neigen dazu, sehr geringe Konsequenz zu sein.

Was können Sie stattdessen tun?

Legen Sie alle Daten, die atomar geschrieben werden müssen, in einen einzigen Pfad. Dann können Sie es als eine einzelne festlegen oder ein Transaktion falls erforderlich.

Oder wenn ein Datensatz der primäre ist und die anderen davon abhängen, schreiben Sie einfach zuerst den primären und dann die anderen in den Callback. Fügen Sie Sicherheitsregeln hinzu, um dies zu erzwingen, sodass der primäre Datensatz immer existiert, bevor die anderen schreiben dürfen.

Wenn Sie Daten einfach denormalisieren, um sie einfach und schnell zu iterieren (z. B. um eine Liste von Namen für Benutzer zu erhalten), indexieren Sie diese Daten einfach in einem separaten Pfad. Dann können Sie den vollständigen Datensatz in einem einzigen Pfad und die Namen, E-Mails usw. in einer schnellen, query / sort-freundlichen Liste haben.

Wann ist das nützlich?

Dies ist ein geeignetes Werkzeug, wenn Sie eine denormalisierte Menge von Datensätzen haben, die:

  • kann praktisch nicht praktisch in einen Pfad zusammengeführt werden
  • haben komplexe Abhängigkeiten (A hängt von C ab, und C hängt von B ab, und B hängt von A ab)
  • -Datensätze werden mit hoher Parallelität geschrieben (d. h. möglicherweise Hunderte von Schreiboperationen pro Minute für den gleichen Datensatz von VERSCHIEDENEN Benutzern)

Wie machst du das?

Die Idee besteht darin, mithilfe von Aktualisierungszählern sicherzustellen, dass alle Pfade dieselbe Revision beibehalten.

1) Erstellen Sie einen Aktualisierungszähler, der mit Transaktionen inkrementiert wird:

%Vor%

2) Geben Sie einige Sicherheitsregeln

%Vor%

3) Geben Sie Ihren Datensätzen Sicherheitsregeln zum Erzwingen des update_counters

%Vor%

4) Schreiben Sie die Daten mit dem update_counter

Da Sicherheitsregeln vorhanden sind, können Datensätze nur erfolgreich geschrieben werden, wenn der Zähler nicht verschoben wird. Wenn es sich bewegt, wurden die Datensätze durch eine gleichzeitige Änderung überschrieben, so dass sie keine Rolle mehr spielen (sie sind nicht mehr die neuesten und größten).

%Vor%

5) Rollbacks

Rollbacks sind etwas komplizierter, können aber von diesem Prinzip abgeleitet werden:

  • Speichern Sie die alten Werte, bevor Sie set
  • aufrufen
  • Überwachen Sie jeden Satz auf Fehler
  • wird bei allen festgeschriebenen Änderungen auf alte Werte zurückgesetzt, aber den neuen Zähler beibehalten

Eine vordefinierte Bibliothek

Ich habe heute eine Lib geschrieben, die das tut und auf GitHub stopft . Fühlen Sie sich frei, es zu benutzen, aber bitte stellen Sie sicher, dass Sie Ihr Leben nicht kompliziert machen, indem Sie lesen "Brauchen Sie das?" oben.

    
Kato 29.01.2014, 23:29
quelle

Tags und Links