Ok, ich kenne den Unterschied zwischen Commit und Rollback und was diese Operationen machen sollen. Ich bin mir jedoch nicht sicher, was ich in Fällen tun soll, in denen ich dasselbe Verhalten bei commit (), rollback () und / oder gar nichts erreichen kann.
Nehmen wir zum Beispiel an, ich habe den folgenden Code, der eine Abfrage ausführt, ohne in db zu schreiben: Ich arbeite an einer Anwendung, die mit SQLite-Datenbank kommuniziert.
%Vor%Oder noch interessanter, betrachten Sie den folgenden Code, der eine einzelne Zeile löscht:
%Vor%Beachten Sie, dass das Commit oder Rollback in den Fällen b) und c) vom semantischen Standpunkt aus zu demselben Verhalten führt.
Im Allgemeinen gibt es in jedem Fall mehrere Möglichkeiten (a, b, c):
Gibt es Richtlinien oder Leistungsvorteile bei der Auswahl einer bestimmten Operation? Was ist der richtige Weg?
Hinweis: Angenommen, die automatische Festschreibung ist deaktiviert.
Wenn es nur eine Auswahl ist, würde ich keine Transaktion öffnen und daher gibt es in keinem Fall etwas zu tun. Wahrscheinlich wissen Sie bereits, dass es ein Update / Insert gibt, da Sie die Parameter bereits übergeben haben. Der Fall, in dem Sie eine Manipulation vornehmen möchten, ist interessanter. Der Fall, in dem es gelöscht wird, ist klar, das Sie festschreiben möchten; Wenn es eine Ausnahme gibt, sollten Sie ein Rollback durchführen, um die Datenbank konsistent zu halten, da etwas fehlgeschlagen ist und Sie nicht viel tun können. Wenn das Löschen fehlgeschlagen ist, weil es nichts zu löschen gab, würde ich aus 3 Gründen committen:
Semantisch scheint es korrekter zu sein, da die Operation war technisch erfolgreich und durchgeführt wie angegeben.
Es ist zukunftssicherer, wenn jemand mehr Code hinzufügt Transaktion werden sie nicht überrascht sein mit dem Rollback, weil ein Löschen hat einfach nichts getan (sie würden auf Ausnahme erwarten dass die Transaktion zurückgesetzt wird)
Wenn es eine Operation gibt, ist Commit schneller, aber in diesem Fall I glaube nicht, dass es wichtig ist.
Für jede nicht-triviale Anwendung müssen Operationen ausgeführt werden, die mehrere SQL-Anweisungen erfordern. Jeder Fehler, der nach der ersten SQL-Anweisung und vor der letzten SQL-Anweisung auftritt, führt dazu, dass Daten inkonsistent sind.
Transaktionen sind so konzipiert, dass Operationen mit mehreren Anweisungen so unteilbar sind wie die Operationen mit einer einzigen Anweisung, mit denen Sie gerade arbeiten.
Ich habe mir die exakt gleiche Frage gestellt. Am Ende entschied ich mich für eine Lösung, bei der ich immer erfolgreiche Transaktionen durchgeführt und immer wieder nicht erfolgreiche Transaktionen rückgängig gemacht habe responses . Dies vereinfachte die Menge an Code und machte es klarer und einfacher zu lesen.
Es hatte keine größeren Leistungsprobleme in der Anwendung, in der ich gearbeitet habe, die NHibernate + SQLite auf .net verwendet. Ihr Kilometerstand kann variieren.
Wie andere in ihren Antworten sagten, handelt es sich nicht um eine Leistung (für die äquivalenten Fälle, die Sie beschrieben haben), die meiner Meinung nach vernachlässigbar ist, sondern eine Frage der Wartbarkeit, und das ist so wichtig!
Damit Ihr Code gut wartbar ist, schlage ich vor (egal was), immer am unteren Rand Ihres try
-Blocks zu committen und Ihr Connection
immer in Ihrem finally
-Block zu schließen. Im Block finally
sollten Sie auch einen Rollback durchführen, wenn nicht festgeschriebene Transaktionen vorliegen (was bedeutet, dass Sie das Commit am Ende des Blocks try
nicht erreicht haben).
Dieses Beispiel zeigt, was ich glaube, ist die beste Praxis (Miantainability-weise):
%Vor%Was Sie sagen, hängt davon ab, wie der Code aufgerufen wird. Gibt er eine Flagge zurück, die Sie testen können, oder gibt er Ausnahmen nur aus, wenn etwas schief geht?
API gibt Ausnahmen aus, gibt aber auch einen booleschen Wert (true | false) zurück:
Diese Situation tritt häufig auf und es erschwert es dem aufrufenden Code, beide Bedingungen zu behandeln, wie Sie in Ihrem OP angegeben haben. Das einzige, was Sie in dieser Situation tun können, ist:
%Vor%API wirft exklusiv Ausnahmen (kein Rückgabewert) :
Kein Problem. Wir können annehmen, dass, wenn keine Ausnahme abgefangen wurde, die Operation ohne Fehler abgeschlossen wurde und wir rollback () / commit () innerhalb des try / catch-Blocks hinzufügen können.
%Vor%API wirft keine Ausnahmen, gibt nur einen bool zurück (true | false):
Das geht zurück auf Old School Fehlerbehandlung / Überprüfung
%Vor%Wenn Sie mehrere Abfragen haben, aus denen die Transaktion besteht, können Sie die Idee der einzelnen Variablen aus Szenario 1 ausleihen:
%Vor%"Hinweis: Angenommen, die automatische Festschreibung ist deaktiviert."
Tags und Links sql java database transactions jdbc