Was passiert, wenn Sie keine Transaktion für eine Datenbank (z. B. SQL Server) festschreiben?

108

Angenommen, ich habe eine Frage:

begin tran
-- some other sql code

Und dann vergesse ich, mich zu verpflichten oder zurückzusetzen.

Was würde passieren, wenn ein anderer Client versucht, eine Abfrage auszuführen?

Charbel
quelle

Antworten:

148

Solange Sie eine Transaktion nicht festschreiben oder rückgängig machen , wird sie immer noch "ausgeführt" und hält möglicherweise Sperren.

Wenn Ihr Client (Anwendung oder Benutzer) die Verbindung zur Datenbank vor dem Festschreiben schließt, werden alle noch laufenden Transaktionen zurückgesetzt und beendet.

marc_s
quelle
1
mmm, ok, ich finde heraus, dass dies eine Art Schloss geschaffen hat. Ich war mir nicht sicher, ob das Schließen der Verbindung mich tatsächlich aus diesem Zustand herausholen würde. Das Problem war, dass ich beim Festschreiben einen Fehler bekam. Jetzt habe ich die Verbindung geschlossen und alles hat funktioniert.
Charbel
12
Randnotiz: Wenn Sie Management Studio verwenden, wird durch Schließen des Abfragefensters die Verbindung geschlossen
Joe Phillips
3
@ BradleyDotNET: Ja, definitiv
marc_s
2
Beachten Sie, dass SQL Server Management Studio automatisch festschreibt, wenn Sie das Abfragefenster / die Verbindung standardmäßig schließen.
Nuno
1
Beachten Sie, dass wenn der Client die Verbindung schließt, während eine Transaktion aktiv ist, diese nicht immer zurückgesetzt wird - dies hängt vom Client und der Datenbank ab. Wenn beispielsweise eine Java-App eine Verbindung zu einer Oracle-Datenbank schließt, werden alle offenen Verbindungen automatisch festgeschrieben.
AviD
38

Sie können dies tatsächlich selbst versuchen, um ein Gefühl dafür zu bekommen, wie dies funktioniert.

Öffnen Sie im Management Studio zwei Fenster (Registerkarten), von denen jedes eine eigene Verbindung zu SQL hat.

Jetzt können Sie eine Transaktion in einem Fenster starten, einige Dinge wie Einfügen / Aktualisieren / Löschen ausführen, aber noch nicht festschreiben. Im anderen Fenster können Sie dann sehen, wie die Datenbank von außerhalb der Transaktion aussieht. Abhängig von der Isolationsstufe kann die Tabelle gesperrt sein, bis das erste Fenster festgeschrieben wird, oder Sie können (nicht) sehen, was die andere Transaktion bisher getan hat usw.

Spielen Sie mit den verschiedenen Isolationsstufen und ohne Sperrhinweis, um zu sehen, wie sie sich auf die Ergebnisse auswirken.

Sehen Sie auch, was passiert, wenn Sie einen Fehler in der Transaktion auslösen.

Es ist sehr wichtig zu verstehen, wie all diese Dinge funktionieren, sonst werden Sie oft überrascht sein, was SQL tut.

Habe Spaß! GJ.

gjvdkamp
quelle
OK, aber wird die Transaktion mindestens vor der Ausgabe des Commits in das Protokoll geschrieben? Angenommen, ich möchte eine Transaktion starten, einen Einfügebefehl ausführen und "etwas anderes tun", bevor ich ein Commit ausführe. Wird mein Einfügebefehl in das Protokoll geschrieben? Auf diese Weise kann der Server, wenn er vor dem Ausführen des Commits abstürzt, wieder dorthin zurückkehren, wo er war, und ich kann das Commit erst später ausgeben (wenn ich mit "etwas anderem" fertig bin).
user1870400
16

Transaktionen sollen vollständig oder gar nicht ausgeführt werden. Die einzige Möglichkeit, eine Transaktion abzuschließen, ist das Festschreiben. Jede andere Möglichkeit führt zu einem Rollback.

Wenn Sie beginnen und dann nicht festschreiben, wird es daher beim Schließen der Verbindung zurückgesetzt (da die Transaktion abgebrochen wurde, ohne als vollständig markiert zu werden).

Piskvor verließ das Gebäude
quelle
So sollte es sein, aber das ist nicht immer der Fall.
FalcoGer
... wie mySQL MyISAM, die es nicht unterstützen Transaktionen, sicher.
Piskvor verließ das Gebäude
3

hängt von der Isolationsstufe der eingehenden Transaktion ab.

SQL-Transaktionsisolation erklärt

Xhalent
quelle
6
Das Verhalten der Transaktionen hängt nicht von der Isolationsstufe ab. Die Anzahl der Sperren, die sie verursachen könnten, ist ausreichend.
marc_s
Ich bin mir ziemlich sicher, welche Daten von einer Verbindung gelesen werden können, hängt definitiv von der Isolationsstufe ab. Wenn Sie die Isolation auf READ UNCOMMITTED gesetzt haben, können Sie Daten lesen, die noch nicht festgeschrieben sind, und möglicherweise irgendwann an der Strecke zurückgesetzt werden. Dies stellt jedoch sicher, dass keine Sperre vorliegt. Wenn Sie READ COMMITTED als Isolationsstufe verwendet haben, können Sie keine nicht festgeschriebenen Zeilen lesen. Der zweite Client bleibt hängen, es sei denn, Sie verwenden SNAPSHOT.
Xhalent
2

Wenn Sie eine Transaktion öffnen, wird nichts von selbst gesperrt. Wenn Sie jedoch einige Abfragen innerhalb dieser Transaktion ausführen, werden abhängig von der Isolationsstufe einige Zeilen, Tabellen oder Seiten gesperrt, sodass andere Abfragen betroffen sind, die versuchen, von anderen Transaktionen aus auf sie zuzugreifen.

Rotklee
quelle
1

Beispiel für eine Transaktion

tran tt beginnen

Ihre SQL-Anweisungen

Wenn ein Fehler aufgetreten ist, wird ein Rollback-Vorgang ausgeführt

Solange Sie keine Festschreibungstransaktion ausgeführt haben, werden die Daten nicht geändert

user3386471
quelle
1
Beachten Sie, dass das Benennen von Transaktionen nicht nur in MS SQL nicht erforderlich ist, sondern auch ein falsches Gefühl der Kontrolle vermitteln kann. BEGIN TRAN X ... BEGIN TRAN Y ... ROLLBACK Yfunktioniert zum Beispiel nicht. Siehe stackoverflow.com/questions/1273376/…
0

Zusätzlich zu den potenziellen Sperrproblemen, die Sie möglicherweise verursachen, werden Sie feststellen, dass Ihre Transaktionsprotokolle zu wachsen beginnen, da sie nicht über den Mindest-LSN für eine aktive Transaktion hinaus abgeschnitten werden können. Wenn Sie die Snapshot-Isolation verwenden, wächst Ihr Versionsspeicher in Tempdb um ähnliche Gründe.

Sie können verwenden dbcc opentran, um Details der ältesten offenen Transaktion anzuzeigen.

Martin Smith
quelle
0

Bei nicht abgeschlossenen Transaktionen bleibt der Server gesperrt, und andere Abfragen werden nicht auf dem Server ausgeführt. Sie müssen die Transaktion entweder zurücksetzen oder festschreiben. Durch das Schließen von SSMS wird auch die Transaktion beendet, sodass andere Abfragen ausgeführt werden können.

Josh Moorish
quelle
-4

Das Verhalten ist nicht definiert, daher müssen Sie explizit ein Commit oder ein Rollback festlegen:

http://docs.oracle.com/cd/B10500_01/java.920/a96654/basic.htm#1003303

"Wenn der Auto-Commit-Modus deaktiviert ist und Sie die Verbindung schließen, ohne Ihre letzten Änderungen explizit festzuschreiben oder zurückzusetzen, wird eine implizite COMMIT-Operation ausgeführt."

Hsqldb macht einen Rollback

con.setAutoCommit(false);
stmt.executeUpdate("insert into USER values ('" +  insertedUserId + "','Anton','Alaf')");
con.close();

Ergebnis ist

2011-11-14 14: 20: 22,519 main INFO [SqlAutoCommitExample: 55] [AutoCommit enabled = false] 2011-11-14 14: 20: 22,546 main INFO [SqlAutoCommitExample: 65] [0 # Benutzer in Datenbank gefunden]

Bernd Schatz
quelle
2
Dies mag für Oracle zutreffen (ich habe keine Ahnung), aber der Fragesteller fragt nach MS-SQL
PaulG
Das erste Anführungszeichen gilt für den JDBC-Treiber, nicht für den Server.
Djechlin