Ist es erforderlich, ROLLBACK zu schreiben, wenn Abfragen fehlschlagen?

8

Ich schreibe

mysql_query("SET AUTOCOMMIT=0");
mysql_query("START TRANSACTION");

bevor ich alle Abfragen schreibe. Dann überprüfe, ob alle wahr sind und schreibe dann:

mysql_query("COMMIT");

Aber wenn eine der Abfragen fehlschlägt, übermittle ich einfach die COMMIT-Abfrage. Also brauche ich wirklich ROLLBACK-Funktion, wenn eine der Abfragen fehlschlägt? Denn ohne ROLLBACK funktioniert es auch.
Danke.

    
good_evening 01.05.2010, 18:40
quelle

5 Antworten

11

Ich denke, Sie fragen, ob das Ausführen von ROLLBACK notwendig ist, da ohne es die Commits immer noch nicht angewendet werden. Das ist technisch wahr, aber nur, weil die Transaktion noch offen ist, da Sie sie nicht beendet haben. Alles, was die Transaktion implizit festschreibt (zum Beispiel das Starten einer neuen Transaktion), verhält sich so, als hätten Sie COMMIT ausgeführt, was das Gegenteil von dem ist, was Sie wollen

    
Michael Mrozek 01.05.2010, 18:47
quelle
5

Der Grund für die Verwendung von Transaktionen besteht darin, mehrere Änderungen zusammenzufassen, damit sie alle atomar erfolgreich sind. Andernfalls können Sie keine Änderungen vornehmen. Mit anderen Worten, wenn eine Änderung fehlschlägt, würde die Transaktion die Datenbank in einem logisch inkonsistenten Zustand belassen.

Beispiel: Ein Konto in einem UPDATE abbuchen und ein anderes Konto in einem separaten UPDATE kreditieren. Dies stellt eine Geldüberweisung dar. Wenn die Lastschrift erfolgreich ist, aber die Gutschrift fehlschlägt, sollten Sie die gesamte Transaktion rückgängig machen, sonst scheint das Geld in Luft aufgelöst zu werden.

Die beabsichtigte Verwendung besteht also darin, die Transaktion rückgängig zu machen, wenn eine der Änderungen fehlschlägt.

Sie scheinen zu sagen, dass es in Ihrer Anwendung in Ordnung ist, wenn eine der Änderungen fehlschlägt. Das lässt mich glauben, dass Sie Änderungen unangemessen in Transaktionen gruppiert haben.

Entscheiden Sie, welche Gruppe von Änderungen müssen alle gemeinsam erfolgreich sind, und fügen Sie diese in eine Transaktion ein. Alle Änderungen, die nicht zu dieser Gruppe gehören, sollten in einer separaten Transaktion enthalten sein.

    
Bill Karwin 01.05.2010 18:45
quelle
1

Sie sollten ROLLBACK explizit verwenden, um deutlich zu machen, was Sie mit jedem tun, der Ihren Code später lesen muss, was Sie möglicherweise sind:)

Auch wenn Sie Code hinzufügen, der nach einem COMMIT / ROLLBACK ausgeführt werden soll, ist es besser, ihn explizit auszulösen, um einen besser vorhersagbaren Zustand Ihrer Daten zu haben. Wenn Sie sich auf automatisches ROLLBACK verlassen, erwartet dieser Code möglicherweise, dass sich die Datenbank im unveränderten Status befindet, während sie sich noch in der nicht übergebenen Transaktion befindet.

    
selfawaresoup 01.05.2010 18:47
quelle
1

Es hängt davon ab, wie Sie die Fehlerbehandlung im Allgemeinen durchführen. Die Verwendung von Transaktionen ist nett, denn wenn Ihr Code innerhalb der Transaktion eine Ausnahme auslöst (was möglicherweise NICHT der Fall sein kann, weil eine Datenbankabfrage fehlgeschlagen ist), führt normalerweise Ihr Ausnahmebehandler zu einem Rollback.

Wenn Sie die Verbindung geschlossen haben, ohne zu committen, zum Beispiel weil der Prozess unerwartet beendet wurde, würde das Rollback implizit erfolgen, was im Allgemeinen eine gute Sache ist (es verbessert die Robustheit, da es beim Neustart des Prozesses erneut versuchen kann) / p>

Nun, natürlich ist die Verwendung von PHP und der "alten" mysql-API nicht geeignet, dies zu korrigieren, da es die Fehlerberichterstattung durch Ausnahmen nicht unterstützt.

Sie können es jedoch umgehen, indem Sie einen PHP-Error-Handler registrieren, der eine Ausnahme auslöst, wenn ein Fehler auftritt, anstatt die Standardmethode "charge headlong in disaster" auszuführen:

%Vor%     
MarkR 01.05.2010 21:03
quelle
1

Wenn Sie PHP so konfiguriert haben, dass persistente MySQL-Verbindungen verwendet werden, führt das NICHT-Zurückrollen von Transaktionen bei einem Fehler zu Problemen bei nachfolgenden Verbindungen. Transaktionen werden nicht automatisch abgebrochen, wenn das Skript abbricht / beendet, da die Verbindung im Hintergrund erhalten bleibt. Jede nachfolgende Wiederverwendung dieser bestimmten Verbindung wird dann weitergehen, als ob nichts passiert wäre, und Sie landen mitten in dieser alten Transaktion.

Wenn die Transaktion irgendwelche Sperren erwirbt, bleiben diese Sperren weiterhin aktiv, bis etwas einen Rollback verursacht oder die Verbindung abbricht (welche automatischen Rollbacks). Sie können einen Protokollstau für andere Abfragen verursachen, wenn sie die gesperrten Tabellen / Zeilen berühren.

    
Marc B 02.05.2010 04:34
quelle

Tags und Links