Ich habe ein Datenbankprotokoll, in dem einige Transaktionen gewinnen (sie werden vor dem Absturz festgeschrieben) und andere verlieren (noch nicht festgeschrieben). Wir haben in der Klasse gelernt, dass die Aktionen der Verlierer rückwärts rückgängig gemacht werden müssen.
Gibt es einen Grund, dies rückwärts zu tun? Kann jemand ein einfaches Beispiel für ein Protokoll geben, bei dem Forward-Rückgängigmachungen zu falschen Ergebnissen führen würden?
concurrency
databases
prjctdth
quelle
quelle
Antworten:
Ursprüngliche Transaktionen:
Rückgängig machen:
quelle
Um die Antwort von DylanSp zu ergänzen, schlägt der Versuch fehl, ein Feld in einem nicht vorhandenen Datensatz zu aktualisieren, aber das Ergebnis ist weiterhin das erwartete Ergebnis: Datensatz r ist nicht vorhanden.
Betrachten Sie jedoch eine Situation, in der das Löschen eines Datensatzes tatsächlich fehlschlägt:
Nehmen wir an, nicht unrealistisch, dass jede OrderLine mit einem Auftrag verknüpft sein muss .
Das Zurücksetzen der Transaktion, die mit dem Löschen der Bestellung beginnt, schlägt fehl, da dies gegen unsere Geschäftsregel verstoßen würde.
So danach
Möglicherweise haben wir eine bestehende Bestellung (ohne Bestellposten).
In diesem Fall könnten wir natürlich ein kaskadierendes Löschen verwenden, aber das würde bedeuten, dass Schritt 2 fehlschlagen würde (ohne Auswirkungen). Schlimmer noch, es kann unerwünschtes Verhalten sein, kaskadierende Löschvorgänge bei Aufträgen zu implementieren.
quelle
Gehen wir analog: Sagen wir, Sie gehen zum Abendessen aus.
Dann bekommst du einen Anruf. Dinnerpläne abgesagt.
Da läuft etwas schief. Sie könnten stolpern und sich verletzen. Oder es ist wahrscheinlicher, dass Sie feststellen, dass einige Aktionen erst rückgängig gemacht werden können, wenn spätere Aktionen zuerst rückgängig gemacht werden.
Wenn Sie das letzte, was Sie getan haben, rückgängig machen, kehren Sie zu dem Zeitpunkt zurück, als der vorletzte Schritt ausgeführt wurde. Dann machst du diesen Schritt rückgängig und wiederholst ihn, bis nichts mehr übrig ist. Andererseits ist das Umkehren des ersten Schritts möglicherweise nicht möglich, wenn die Zustände den späteren Schritten folgen.
Mathematisch gesprochen: Die Aktionen werden möglicherweise nicht umgesetzt. Wann immer es also darauf ankommt, welchen Schritt Sie zuerst oder zweitens ausführen, spielt die Reihenfolge, in der Sie Schritte rückgängig machen, eine Rolle.
quelle
Dies ist richtig, da Transaktionen aufeinander aufbauen und das Ergebnis einer Transaktion stark von der Situation vor dem Commit abhängt.
Schauen wir uns die Finanztransaktionen an:
(zu Beginn, bevor Transaktionen
a
mir 100 USD schulden)a
schuldet mir 100 USD (jetzt Gesamtschuld 200)a
erhält 10% Rabatt auf das, was er mir schuldet. (jetzt Gesamtverschuldung 180)Angenommen, ich möchte die beiden Transaktionen stornieren.
Wenn wir die erste zuerst stornieren, erhalten wir:
Das ist falsch, wir müssen die Schulden von 100 zurückzahlen. Das ist richtig, wenn wir die Transaktionen in umgekehrter Reihenfolge stornieren.
quelle
Angenommen, es gibt eine Tabelle T mit nur einer Spalte.
Angenommen, das "Undo-Protokoll" ist eine Datenbankdatei, die nicht festgeschriebene Transaktionen enthält, und das "Redo-Protokoll" ist eine Datenbankdatei, die sowohl nicht festgeschriebene als auch festgeschriebene Transaktionen enthält, die noch nicht auf die Datendateien angewendet wurden.
At 8:00 A.M., Transaction 100 inserts rows with values 101, 102 and 103 into table T. At 8:10 A.M., Transaction 100 is committed and the commit for transaction 100 completes. At 8:15 A.M., Transaction 200 updates row 101 to 201, 102 to 202 and 103 to 203. At 8:20 A.M., Transaction 200 has not been committed and remains in the undo log of the database. At 8:25 A.M., Transaction 300 increments each row by 50, changing row 201 to 251, 202 to 252, and 203 to 253. At 8:30 A.M., Transaction 300 has not been committed and remains in the undo log of the database. At 8:35 A.M., The instance providing access to the database crashes.
At 8:40 A.M., The instance is restarted, and the database files are opened as the instance is started:
At 8:41 A.M., The redo log has been applied, and the T table contains values 251, 252 and 253 in the instance memory.
At 8:42 A.M., The undo log is applied in the reverse order: Uncommitted transaction 300 is undone, and Uncommitted transaction 200 is undone.
Warum werden BEIDE festgeschriebenen und nicht festgeschriebenen Transaktionen in die Redo-Log-Datei geschrieben? Der Grund hierfür ist die Bereitstellung einer Wiederherstellung zu einem bestimmten Zeitpunkt.
Dies bedeutet, dass der Inhalt der Datei "Redo Log" NICHT transaktionskonsistent ist. Aus diesem Grund MUSS das "Rückgängig-Protokoll" immer dann verwendet werden, wenn das Redo-Protokoll verwendet wird, um festgeschriebene Transaktionen auf die Datendateien anzuwenden, um nicht festgeschriebene Transaktionen zurückzusetzen.
Warum werden die Transaktionen im "Undo-Log" in umgekehrter Reihenfolge zurückgesetzt? Die Transaktion 300 hat zu dem vorhandenen Wert jeder Spalte jeder Zeile 50 addiert. Wenn daher die Transaktion 200 zuerst zurückgesetzt wird, ändern sich die Werte von 251, 252 und 253 zu 201, 202 und 203. Wenn die Transaktion 300 dann zuletzt zurückgesetzt würde, wären die Werte 151, 152 und 153 - die nicht übereinstimmen die ursprünglich zugesagten Werte.
VERWEISE:
https://asktom.oracle.com/pls/asktom/f?p=100:11:0:::P11_QUESTION_ID:1670195800346464273
quelle
Es ist nicht von Natur aus wahr. Beim Rollback werden die im Rückgängig-Protokoll zwischengespeicherten Blöcke möglicherweise erneut angewendet, sodass der endgültige Status dem ursprünglichen Status entspricht. Da das Protokoll in Vorwärtsreihenfolge geschrieben wurde, habe ich mein Rollback auch in Vorwärtsreihenfolge angewendet. Die Reihenfolge spielte keine Rolle, da das Rollback so lange wiederholt wurde, bis die Protokolldatei als erledigt markiert wurde.
quelle