Wenn Sie sich nur die Datenbank ansehen, ist alles in Ordnung. Sie haben Transaktionen und wenn etwas schief geht, wird alles zurückgesetzt. Das ist schön - ich mag das.
ABER: Ich möchte Mails senden. Jetzt bin ich in Schwierigkeiten, weil ich nicht zurückrollen kann.
Beispiel:
- Transaktion beginnt
- Mail wird gesendet
- Andere Dinge werden erledigt (innerhalb der DB)
- Etwas läuft schief.
- Rollback.
Wie man das löst, ist eine andere Frage, nicht diese.
Diese Frage, wie man das allgemein nennt. In diesem Beispiel geht es um das Versenden von E-Mails. Aber das gleiche Problem, sobald Sie etwas in Systemen ändern, die außerhalb der Transaktionsgrenze liegen.
Gibt es einen Namen für dieses Problem ?
Etwa das gleiche Problem tritt auf, wenn Sie Dateien aus einem Verzeichnis importieren möchten. Wenn Sie die Datei innerhalb der Transaktion löschen, schlägt die Transaktion möglicherweise fehl und die Datei wurde gelöscht, aber nie importiert. Oder Sie löschen die Datei nach der Transaktion. Dann schlägt das Löschen der Datei möglicherweise fehl und die Datei wird ein zweites Mal importiert.
Ich möchte keine Lösung dafür neu erfinden. Deshalb brauche ich den passenden Begriff für dieses Problem. Dann kann ich einige Artikel lesen und erfahren, was "Stand der Technik" im Jahr 2018 ist.
quelle
Antworten:
Sie beschreiben eine verteilte Transaktion . Beachten Sie, dass der Begriff "Transaktion" eine allgemeinere Bedeutung hat als nur "Datenbanktransaktion".
In einer verteilten Transaktion haben verschiedene Mitglieder möglicherweise unterschiedliche ACID-Eigenschaften (z. B. muss die Zustellung von E-Mails nicht unbedingt garantiert werden), unterschiedliche Ansätze zum Erreichen dieser Eigenschaften und unterschiedliche Fehlerszenarien.
Um die Konsistenz einer verteilten Transaktion sicherzustellen, wird normalerweise eine externe Entität namens Transaktionskoordinator (oder -manager) eingesetzt, um das Engagement jedes Mitglieds zu steuern (kann auch als Ressource oder Ressourcenmanager bezeichnet werden). Eine übliche Methode ist das Two-Phase-Commit (2PC).
Wenn Sie im Internet nach "Konsistenz in verteilten Systemen" suchen, finden Sie eine Vielzahl von Materialien zu diesem Thema.
quelle
Das Oracle PL / SQL-Schlüsselwort
AUTONOMOUS_TRANSACTION
bewirkt, dass eine Prozedur eine weitere Sitzung erstellt, eine Transaktion ausführt, nur diese private Transaktion festschreibt / zurücksetzt und die Flusskontrolle an das übergeordnete Element zurückgibt.Oh ... senden Sie niemals E-Mails mit nicht festgeschriebenen Daten.
BEARBEITEN: (aufgrund der Bearbeitung des ursprünglichen Beitrags)
Diese Art von Problem wird als a bezeichnet
bug
.Die Lösung ist:
TRANSACTION
COMMIT
.E-MAIL-Beispiel
Sie sollten eine Prozedur haben, nach
sendEmail
der aufgerufen werden solltecommit
.Wenn Sie die Prozedur vorher aufrufen möchten
commit
, müssen Sie einer Warteschlange, dierollback
die Haupttransaktion enthält , eine Zeile hinzufügen . Für Oracle ist dies entwederAdvance Queuing
oder das PaketAPEX_MAIL
Wenn Sie es in ein separates Verfahren einfügen, können Sie es
sendEmail
auf Anfrage des [Endbenutzers] ein zweites Mal tun.Datei verarbeiten
Sie haben einen Algorithmus, der einige Schritte enthält, bei denen jeder Schritt fehlschlagen kann. Das ist eigentlich anders als dein
sendEmail
Problem.Sie müssen aufzeichnen, was Sie verarbeiten, wo Sie sich in Ihrem Algorithmus befinden und ob dieser Schritt erfolgreich war oder fehlgeschlagen ist.
Um einen Fehler in einem beliebigen Schritt zu beheben, muss jeder Schritt des Prozesses als diskret definiert werden
TRANSACTION
.In Oracle hätte ich folgende Prozeduren (1 Prozedur pro
TRANSACTION
):Dies basiert auf den folgenden Tabellen:
Die
UNIQUE
Einschränkung fürFILE_NAME
verhindert, dass dieselbe Datei zweimal verarbeitet wird.quelle
Ich denke, vielleicht ist der Begriff, den Sie suchen, schmutzig gelesen :
quelle
Was Sie beschreiben, ist der Wunsch nach einer verteilten Transaktion, nur dass Sie keinen verteilten Transaktionsmanager und keine Rollback-Möglichkeit haben. Am einfachsten ist es, die Warteschlange (extern) oder den SQL Server-Broker zu verwenden, um die Schleife vom eigentlichen Sendevorgang zu entkoppeln. Siehe zum Beispiel: http://python-rq.org/
quelle
Ich habe keinen bestimmten Begriff für die tatsächliche Kombination des Aufrufs eines externen Prozesses aus einer Datenbanktransaktion, aber ich würde dieses Problem als eng gekoppelt klassifizieren .
Das Hauptproblem besteht darin, dass Sie das Senden der E-Mail eng mit der Datenbanktransaktion verknüpft haben .
Eine Lösung für dieses Problem besteht darin, sie lose zu koppeln .
Technisch könnte man dies auf viele Arten lösen, in grober Reihenfolge von hässlich bis nett:
quelle
Implizite Commits
Ich glaube, das ist der Begriff, den Sie suchen. Dies sind Aussagen, die nicht eingehalten werden / können und werden
Transactions
Orakel
MySQL
SQL Server
Datenbank-ddls-und-implizites Festschreiben
und am interessantesten Dies:
sp_send_dbmail (Transact-SQL)
Der Workflow braucht nur Aufmerksamkeit,
Anstatt
VERSUCHEN
(Erfassen Sie die Anzahl der Endzeilen in einer Variablen B oder Datei.)
und wenn A & B-Variablen übereinstimmen, wissen Sie, dass ein Fehler vorliegt.
Ändern Sie den Workflow und versuchen Sie, das, was Sie bereits haben, zu Ihrem Vorteil, zum Variablenvergleich usw. zu nutzen.
quelle
Dies ist ein Problem, das in der Phase "Requirements Engineering" des Projekts nicht berücksichtigt wurde. Es sollte nicht als Problem des Datenbanksystems angesehen werden, da die Datenbank die ordnungsgemäße Leistung erbringt. Die Mail wird gesendet, weil sie (noch) nicht Teil der richtigen Geschäftslogik ist.
Es wird als Business Logic-Fehler oder möglicherweise sogar als Business Logic-Problem bezeichnet .
Geschäftslogik
Referenz: Geschäftslogik (Wikipedia.org)
Fehler / Probleme in der Geschäftslogik
Referenz: Sicherheitslücken in der Geschäftslogik und einige häufige Szenarien von Fehlern in der Geschäftslogik (Cyber Security Community)
Referenz: Häufige Fehler in der Geschäftslogik, die die Anwendungssicherheit beeinträchtigen (SecurityWeek.com)
quelle