9 Stimmen

Atomare Operationen auf mehreren transaktionslosen externen Systemen

Angenommen, Sie haben eine Anwendung, die 3 verschiedene externe Systeme verbindet. Sie müssen etwas in allen 3 Systemen aktualisieren. Im Falle eines Fehlers müssen Sie die Vorgänge rückgängig machen. Das ist nicht schwer zu implementieren, aber nehmen wir an, Operation 3 schlägt fehl, und beim Rollback schlägt das Rollback für Operation 1 fehl! Jetzt befindet sich das erste externe System in einem ungültigen Zustand...

Ich denke, eine mögliche Lösung besteht darin, die Anwendung zu beenden und eine manuelle Korrektur des externen Systems zu erzwingen, aber dann wiederum... Vielleicht hat es diese Informationen bereits verwendet (und ist deshalb gescheitert), oder wir haben keinen ausreichenden Zugang. Oder es ist vielleicht nicht einmal eine gute Möglichkeit, die Aktion rückgängig zu machen!

Gibt es gute Methoden für den Umgang mit solchen Fällen?

EDIT: Einige Details zur Bewerbung

Es handelt sich um eine Webanwendung für mehrere Benutzer. Der größte Teil der Arbeit wird mit geplanten Aufträgen (über Quartz.Net) erledigt, so dass die meisten Vorgänge in einem eigenen Thread ausgeführt werden. Einige Benutzeraktionen sollten jedoch Jobs auslösen, die mehrere Systeme aktualisieren. Die externen Systeme sind etwas unstabil.

Ich dachte daran, die Anwendung so zu ändern, dass sie das Muster "Befehl und Arbeitseinheit" verwendet.

1voto

Oddthinking Punkte 22694

Zwei-Phasen-Commit ( 2PC ) könnte hier geeignet sein.

In der ersten Phase müssen die verschiedenen Datenbanken zustimmen, dass sie mit der Übergabe fortfahren. In Ihrem Beispiel wird Datenbank 1 erst dann mit dem Schreibvorgang fortfahren, wenn sie sicher ist, dass alle drei Datenbanken gemeldet haben, dass die Transaktion möglich sein wird.

Im Gegensatz dazu handelt es sich bei dem von Ihnen beschriebenen Prozess um einen "optimistischen" Ansatz: Datenbank 1 geht davon aus, dass die Transaktion durchgeführt werden sollte, bis sie etwas anderes erfährt und zum Rollback gezwungen wird.

1voto

Oddthinking Punkte 22694

Möchten Sie näher erläutern, wie der Rollback von Vorgang 1 fehlschlagen konnte?

Der Zustand, den er anstrebt, ist ein Zustand, den er schon einmal hatte, also sollte er logisch konsistent sein. Es könnte vorübergehende Probleme geben, wie z. B. Netzwerkausfälle, aber es könnte der Fall sein, dass der beste Weg, damit umzugehen, darin besteht, es erneut zu versuchen, bis die Probleme verschwunden sind.

Wenn das Problem darin besteht, dass nachfolgende Transaktionen die Daten in der Zwischenzeit gesperrt oder geändert haben, dann haben Sie ein viel größeres Problem - Ihre Transaktionen sind nicht atomar, und ihre Rücknahme kann dazu führen, dass die Ausgabe anderer Transaktionen ungültig wird.

0voto

Ant Punkte 4840

Je nach Größe der Anwendung (Einzelbenutzer oder Unternehmen) kann es eine schlechte Idee sein, die Anwendung abzuschalten.

Zunächst einmal würde ich vorschlagen, den Ausgangszustand der Informationen, die in den 3 externen Anwendungen geändert werden, in einem lokalen Speicher Ihrer eigenen Anwendung zu speichern. So können Sie zumindest feststellen, wie der Rollback-Status aussehen soll, falls Ihre App abstürzt/der Rollback fehlschlägt/etc. Sobald die Transaktion erfolgreich abgeschlossen wurde, können Sie diese Daten löschen.

Was zu tun ist, wenn einer der Vorgänge ausfällt, hängt von der Funktionalität der 3 externen Systeme ab. Nehmen wir an, dass eines dieser Systeme Mitarbeiterdaten enthält. Die Anwendung abzuschalten, nur weil die Adresse eines Mitarbeiters aufgrund einer fehlgeschlagenen Transaktion falsch ist, wäre übertrieben. Viel besser ist es, bei jedem Zugriff auf die Daten eines Mitarbeiters das Protokoll der fehlgeschlagenen Transaktion zu überprüfen (d. h. den lokalen Speicher, in dem Sie die Ausgangszustände der drei externen Anwendungen gespeichert haben). Wenn diese Mitarbeiterdaten als ungültig gekennzeichnet sind, geben Sie eine Fehlermeldung aus, die besagt, dass sich der Datensatz in einem ungültigen Zustand befindet und nicht abgerufen werden kann.

Wenn jedoch das gesamte externe System durch eine fehlgeschlagene Transaktion durcheinander gebracht wird, dann können Sie nichts anderes tun, als Ihre Anwendung herunterzufahren, bis das Problem behoben ist.

0voto

Donal Fellows Punkte 125686

Die Antwort von Oddthinking ist gut, aber begrenzt, weil es sehr schwierig ist, tatsächlich zuverlässig einen 2PC machen. Dies ist in der Distributed-Computing-Gemeinschaft schon seit geraumer Zeit bekannt, obwohl viele Leute ihr Bestes tun, um es einfach zu ignorieren.

Wenn Sie sich eingehender mit diesem Thema befassen möchten, können Sie die Paxos-Konsens-Algorithmus ist ein guter Startpunkt. Und seien Sie sich bewusst, dass dies ein überraschend schwieriges Problem ist, und zwar sowohl wegen der Probleme, auf die Sie anspielen, als auch wegen der Tatsache, dass es eigentlich unmöglich ist, ein wirklich zuverlässiges Nachrichtensystem zu bauen, das eine Nachricht in einer bestimmten Zeit zustellen kann. (Um zu verstehen, warum das so ist, bedenken Sie, dass jemand mit einem Bagger könnte alle Netzwerkverbindungen zwischen den verschiedenen kommunizierenden Parteien auslöschen )

Ich vermute, dass die eigentliche Lösung darin besteht, die Architektur des Gesamtsystems und die Art und Weise, wie Änderungen vorgenommen werden, so zu gestalten, dass ein Ausfall der Kommunikation in einem Bereich nicht zu einer Katastrophe führt. Je nach den genauen Einzelheiten ist dies nicht immer einfach.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X