2008-10-13 6 views
20

Das interne Anwendungsframework, das wir in meinem Unternehmen verwenden, macht es notwendig, jede SQL-Abfrage in Transaktionen zu schreiben, obwohl ich weiß, dass keiner der Befehle Änderungen in der Datenbank vornimmt. Am Ende der Sitzung, vor dem Schließen der Verbindung, verpflichte ich die Transaktion, um sie ordnungsgemäß zu schließen. Ich frage mich, ob es einen besonderen Unterschied gab, wenn ich es zurückbrachte, besonders in Bezug auf die Geschwindigkeit.Gibt es einen Unterschied zwischen Commit und Rollback in einer Transaktion, die nur ausgewählt hat?

Bitte beachten Sie, dass ich Oracle verwende, aber ich denke, andere Datenbanken haben ein ähnliches Verhalten. Außerdem kann ich nichts über die Anforderung machen, die Transaktion zu beginnen, dieser Teil der Codebasis liegt nicht in meiner Hand.

Antwort

12

Datenbanken enthalten oft entweder ein Vorher-Bild-Journal (was es vor der Transaktion war) oder ein Nach-Image-Journal (was es sein wird, wenn die Transaktion abgeschlossen ist.) Wenn es ein Vorher-Bild enthält, muss das sein bei einem Rollback wiederhergestellt. Wenn es ein Nachbild enthält, muss dieses im Falle eines Commits die Daten ersetzen.

Oracle hat sowohl einen Journal- als auch einen Rollback-Speicherplatz. Das Transaktionsjournal akkumuliert Blöcke, die später von DB-Schreibern geschrieben werden. Da diese asynchronen sind, hat fast nichts DB Writer Auswirkungen auf Ihre Transaktion (wenn die Warteschlange füllt, dann müssen Sie möglicherweise warten.)

Auch für eine Abfrage-Transaktion bin ich bereit zu wetten dass es in den Rollback-Bereichen von Oracle ein bisschen Transaktionsrekord gibt. Ich vermute, dass ein Rollback eine gewisse Arbeit an Oracle erfordert, bevor es feststellt, dass es nichts gibt, was tatsächlich rückgängig gemacht werden kann. Und ich denke, das ist synchron mit Ihrer Transaktion. Sie können keine Sperren wirklich freigeben, bis das Rollback abgeschlossen ist. [Ja, ich weiß, dass Sie keine in Ihrer Transaktion verwenden, aber das Sperrproblem ist, warum ich denke, ein Rollback muss vollständig freigegeben werden dann können alle Sperren freigegeben werden, dann ist Ihr Rollback beendet.]

Ein Auf der anderen Seite ist das Commit mehr oder weniger das erwartete Ergebnis, und ich vermute, dass das Löschen des Rollback-Bereichs möglicherweise etwas schneller ist. Sie haben keine Transaktionseinträge erstellt, so dass der db writer niemals aufwachen wird, um zu überprüfen und festzustellen, dass nichts zu tun ist.

Ich erwarte auch, dass, während Commit schneller sein kann, die Unterschiede gering sein werden. So geringfügig, dass Sie sie vielleicht nicht einmal in einem direkten Vergleich messen könnten.

+5

Ich erkenne das nicht als eine Beschreibung der Art und Weise wie Orakel überhaupt funktioniert. Es klingt wie eine generische Beschreibung, die auf Oracle angewendet wurde. Vermutungen, wie Oracle arbeitet, sind wahrscheinlich nicht hilfreich. –

+0

Oracle ruft das Journal eine "Redo Log File" auf. Er ruft die Rollback-Segmente als "Rückgängig-Tablespace" auf. Weißt du, was schneller ist? Commit oder Rollback? –

+0

Wenn es keine Arbeit zu tun gibt, gibt es fast sicher keinen Unterschied. Oracle ist für schnelles Commit optimiert - es erfordert nur, dass der Commit-Datensatz in den Redo-Log-Puffer geschrieben und der Puffer geleert wird (außer bei asynchronem Commit in 10g +). Ein Rollback ist mehr Arbeit. –

0

Da Sie keine DML gemacht haben, vermute ich, dass es keinen Unterschied zwischen einem COMMIT und ROLLBACK in Oracle geben würde. In jedem Fall gibt es nichts zu tun.

4

Im Allgemeinen ist ein COMMIT viel schneller als ein ROLLBACK, aber in dem Fall, wo Sie nichts getan haben, sind sie effektiv gleich.

8

Ich stimme den vorherigen Antworten zu, dass es in diesem Fall keinen Unterschied zwischen COMMIT und ROLLBACK gibt. Es kann einen vernachlässigbaren Unterschied in der CPU-Zeit geben, die benötigt wird, um festzustellen, dass nichts zu COMMIT versus der CPU-Zeit benötigt wird, um zu bestimmen, dass nichts zu ROLLBACK ist. Aber, wenn es ein vernachlässigbarer Unterschied ist, können wir es sicher vergessen.

Es sollte jedoch darauf hingewiesen werden, dass zwischen einer Sitzung, die eine Reihe von Abfragen im Kontext einer einzelnen Transaktion durchführt, und einer Sitzung, die dieselben Abfragen im Kontext einer Reihe von Transaktionen durchführt, ein Unterschied besteht.

Wenn ein Client eine Transaktion startet, eine Abfrage ausführt, einen COMMITor ROLLBACK ausführt, dann eine zweite Transaktion startet und eine zweite Abfrage ausführt, kann nicht garantiert werden, dass die zweite Abfrage den gleichen Datenbankstatus wie die erste Abfrage aufweist. Manchmal ist es wichtig, eine einzige konsistente Ansicht der Daten aufrechtzuerhalten. Manchmal ist es wichtig, eine aktuellere Ansicht der Daten zu erhalten. Es hängt davon ab, was Sie tun.

Ich weiß, ich weiß, das OP hat diese Frage nicht gestellt. Aber einige Leser fragen es vielleicht im Hinterkopf.

3

Die Dokumentation heißt es:

  • Oracle empfiehlt, ausdrücklich jede Transaktion in Ihrem Anwendungsprogramm mit einer COMMIT oder ROLLBACK-Anweisung, einschließlich der letzten Transaktion zu beenden, bevor sie von Oracle Database trennen. Wenn Sie die Transaktion nicht explizit festschreiben und das Programm abnormal beendet wird, wird die letzte nicht festgeschriebene Transaktion automatisch zurückgesetzt. Ein normaler Exit aus den meisten Oracle-Dienstprogrammen und -Tools führt dazu, dass die aktuelle Transaktion festgeschrieben wird. Ein normaler Exit von einem Oracle-Precompiler-Programm setzt die Transaktion nicht fest und beruht auf Oracle Database, um die aktuelle Transaktion zurückzusetzen.

http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/statements_4010.htm#SQLRF01110

Wenn Sie o wählen eine oder das andere zu tun, dann könnten Sie auch das eine tun, die die gleiche wie nichts zu tun ist, und es nur begehen.

+0

Es hängt eigentlich vom Client ab. sqlplus ist ein implizites Commit. andere könnte es nicht sein. Wenn die Netzwerkverbindung getrennt wird (z. B. der Client "nur geht"), dann ist es ein Rollback. –

+0

Ich bin mir nicht sicher, dass es hängt von der Anwendung, ich hätte wahrscheinlich eine "anmutige Trennung" gesagt, aber die Dokumente sagen, dass "eine implizite Anfrage tritt nach der normalen Beendigung einer Anwendung oder ..." http://download.oracle.com/docs/cd/B28359_01/server.111/b28318/transact.htm # CNCPT1119 –

+0

Eigentlich habe ich eine bessere Referenz gefunden und mein Posting bearbeitet. Vielen Dank. –

1

Nun, wir müssen berücksichtigen, was ein SELECT in Oracle zurückgibt. Es gibt zwei Modi. Standardmäßig gibt ein SELECT Daten zurück, da diese Daten genau in dem Moment angezeigt wurden, in dem die SELECT-Anweisung gestartet wurde (dies ist das Standardverhalten im READ COMMITTED-Isolationsmodus, dem Standardtransaktionsmodus). Wenn also ein UPDATE/INSERT ausgeführt wurde, nachdem SELECT ausgegeben wurde, ist dies in der Ergebnismenge nicht sichtbar.

Dies kann ein Problem sein, wenn Sie zwei Ergebnissätze vergleichen müssen (z. B. Debta und Kreditseiten einer Hauptbuch-App). Dafür haben wir einen zweiten Modus. In diesem Modus gibt SELECT Daten zurück, die zu dem Zeitpunkt angezeigt wurden, an dem die aktuelle Transaktion gestartet wurde (Standardverhalten in den Isolationsstufen READ ONLY und SERIALIZABLE).

So, zumindest manchmal ist es notwendig, SELECTs in der Transaktion auszuführen.

0

Ich würde denken, ein Commit wäre effizienter; im Allgemeinen würden Sie erwarten, dass die meisten DB-Transaktionen festgeschrieben werden; Sie würden also denken, dass die DB für diesen Fall optimiert ist (im Gegensatz zu dem Versuch, für einen Rollback effizienter zu sein).