Es macht nichts. Alle einzelnen SQL-Anweisungen (mit seltenen Ausnahmen wie Masseneinfügungen ohne Protokoll oder Tabelle abschneiden) werden automatisch "In einer Transaktion" angezeigt, unabhängig davon, ob Sie dies ausdrücklich sagen oder nicht. (Selbst wenn sie Millionen von Zeilen einfügen, aktualisieren oder löschen.) .
BEARBEITEN: basierend auf dem Kommentar von @ Phillip unten ... In aktuellen Versionen von SQL Server schreiben Even Bulk Inserts und Truncate Table einige Daten in das Transaktionsprotokoll, wenn auch nicht so viele wie andere Vorgänge. Der entscheidende Unterschied aus Transaktionssicht besteht darin, dass bei diesen anderen Arten von Vorgängen die Daten in Ihren Datenbanktabellen, die geändert werden, nicht im Protokoll in einem Zustand sind, in dem sie zurückgesetzt werden können.
Dies bedeutet lediglich, dass die Änderungen, die die Anweisung an Daten in der Datenbank vornimmt, im Transaktionsprotokoll protokolliert werden, sodass sie rückgängig gemacht werden können, wenn der Vorgang fehlschlägt.
Die einzige Funktion, die die Befehle "Transaktion starten", "Transaktion festschreiben" und "RollBack-Transaktion" bereitstellen, besteht darin, dass Sie zwei oder mehr einzelne SQL-Anweisungen in dieselbe Transaktion einfügen können.
BEARBEITEN: (um den Markenkommentar zu verstärken ...) JA, dies könnte auf "abergläubische" Programmierung zurückgeführt werden, oder es könnte ein Hinweis auf ein grundlegendes Missverständnis der Art von Datenbanktransaktionen sein. Eine gemeinnützigere Interpretation ist, dass es einfach das Ergebnis einer unangemessenen Überanwendung von Konsistenz ist und ein weiteres Beispiel für Emersons Euphemismus, dass:
Eine dumme Konsequenz ist der Hobgoblin kleiner Geister, der
von kleinen Staatsmännern, Philosophen und Göttern verehrt wird
TRUNCATE TABLE
. in einer Transaktion Der Grund dafür, dass es immer noch effizienter ist alsDELETE
bei der Protokollierung, ist, dass nur die Seitenfreigaben und nicht die Zeilen protokolliert werden.Wie Charles Bretana sagte, "es tut nichts" - nichts zusätzlich zu dem, was bereits getan wurde.
Haben Sie schon einmal von den "ACID" -Anforderungen einer relationalen Datenbank gehört? Dieses "A" steht für Atomic, was bedeutet, dass entweder die Anweisung vollständig funktioniert oder nicht - und während die Anweisung ausgeführt wird, können keine weiteren Abfragen für die von dieser Abfrage betroffenen Daten durchgeführt werden. BEGIN TRANSACTION / COMMIT "erweitert" diese Sperrfunktion auf die Arbeit mehrerer Anweisungen, fügt jedoch einzelnen Anweisungen nichts hinzu.
Das Datenbanktransaktionsprotokoll wird jedoch immer geschrieben, wenn eine Datenbank geändert wird (Einfügen, Aktualisieren, Löschen). Dies ist keine Option, eine Tatsache, die dazu neigt, Menschen zu irritieren. Ja, es gibt Seltsamkeiten bei Masseneinfügungen und Wiederherstellungsmodi, aber es wird immer noch darauf geschrieben.
Ich werde auch hier Isolationsstufen benennen. Wenn Sie sich damit beschäftigen, wirkt sich dies auf einzelne Befehle aus. Wenn Sie dies tun, wird eine deklarierte, mit Transaktionen umschlossene Abfrage jedoch nicht anders ausgeführt als eine "eigenständige" Abfrage. (Beachten Sie, dass sie bei deklarierten Transaktionen mit mehreren Anweisungen sehr leistungsfähig und sehr gefährlich sein können.) Beachten Sie auch, dass "nolock" nicht für Einfügungen / Aktualisierungen / Löschungen gilt - diese Aktionen erforderten immer Sperren.
quelle
Wenn ich eine einzelne Anweisung in eine Transaktion einbinde, kann ich sie zurücksetzen, wenn ich beispielsweise beim Ausführen einer manuellen, einmaligen UPDATE-Anweisung eine WHERE-Klausel vergesse. Es hat mich ein paar Mal gerettet.
z.B
-------------------------------------------------------------- CREATE TABLE T1(CPK INT IDENTITY(1,1) NOT NULL, Col1 int, Col2 char(3)); INSERT INTO T1 VALUES (101, 'abc'); INSERT INTO T1 VALUES (101, 'abc'); INSERT INTO T1 VALUES (101, 'abc'); INSERT INTO T1 VALUES (101, 'abc'); INSERT INTO T1 VALUES (101, 'abc'); INSERT INTO T1 VALUES (101, 'abc'); INSERT INTO T1 VALUES (101, 'abc'); SELECT * FROM T1 -------------------------------------------------------------- /* MISTAKE SCENARIO (run each row individually) */ -------------------------------------------------------------- BEGIN TRAN YOUR_TRANS_NAME_1; /* open a trans named YOUR_TRANS_NAME_1 */ UPDATE T1 SET COL2 = NULL; /* run some update statement */ SELECT * FROM T1; /* OOPS ... forgot the where clause */ ROLLBACK TRAN YOUR_TRANS_NAME_1; /* since it did bad things, roll it back */ SELECT * FROM T1; /* tans rolled back, data restored. */ -------------------------------------------------------------- /* NO MISTAKES SCENARIO (run each row individually) */ -------------------------------------------------------------- BEGIN TRAN YOUR_TRANS_NAME_2; UPDATE T1 SET COL2 = 'CBA' WHERE CPK = 4; /* run some update statement */ SELECT * FROM T1; /* did it correctly this time */ COMMIT TRAN YOUR_TRANS_NAME_2 /* commit (close) the trans */ -------------------------------------------------------------- DROP TABLE T1 --------------------------------------------------------------
quelle
Eine mögliche Entschuldigung ist, dass diese einzelne Anweisung dazu führen kann, dass eine Reihe anderer SQL-Anweisungen über Trigger ausgeführt werden, und dass sie vor einem Fehler schützen, obwohl ich davon ausgehen würde, dass jedes DBMS den gesunden Menschenverstand hat, implizite Transaktionen zu verwenden genauso schon.
Die andere Sache, die ich mir vorstellen kann, ist, dass Sie mit einigen APIs die automatische Festschreibung deaktivieren können und der Code nur für den Fall geschrieben wurde, dass jemand dies tut.
quelle
Wenn Sie eine explizite Transaktion starten und a ausgeben
DML
, bleiben die von der Anweisung gesperrten Ressourcen gesperrt, und die Ergebnisse der Anweisung sind von außerhalb der Transaktion erst sichtbar, wenn Sie sie manuell festschreiben oder zurücksetzen.Dies ist, was Sie möglicherweise benötigen oder nicht.
Zum Beispiel möchten Sie der Außenwelt möglicherweise vorläufige Ergebnisse anzeigen, während Sie diese weiterhin im Auge behalten.
In diesem Fall starten Sie eine andere Transaktion, bei der eine Sperranforderung vor der ersten Festschreibung gestellt wird, wodurch die Racebedingung vermieden wird
Implizite Transaktionen werden sofort nach
DML
Abschluss oder Fehlschlagen der Anweisung festgeschrieben oder zurückgesetzt .quelle
SQL Server verfügt über eine Einstellung, mit der das automatische Festschreiben für eine Sitzung deaktiviert werden kann. Dies ist sogar die Standardeinstellung für einige Clients (siehe https://docs.microsoft.com/en-us/sql/t-sql/statements/set-implicit-transactions-transact-sql?view=sql-server-2017 ).
Abhängig von einem Framework und / oder einem Datenbankclient, den Sie verwenden, kann das Nichteinfügen jedes einzelnen Befehls in eine eigene Transaktion dazu führen, dass alle Befehle zu einer Standardtransaktion zusammengefasst werden. Das explizite Einschließen jedes einzelnen von ihnen in eine Transaktion erklärt eindeutig die Absicht und stellt tatsächlich sicher, dass dies so geschieht, wie es der Programmierer beabsichtigt hat, unabhängig von der aktuellen Einstellung für die automatische Festschreibung, insbesondere wenn es keine unternehmensweite Richtlinie für die automatische Festschreibung gibt.
Wenn die Befehle begin tran / commit tran in der Datenbank beobachtet werden (gemäß Ihrem Kommentar hier ), ist es auch möglich, dass ein Framework sie im Auftrag eines ahnungslosen Programmierers generiert. (Wie viele Entwickler überprüfen den von ihrem Framework generierten SQL-Code genau?)
Ich hoffe, dass dies immer noch relevant ist, obwohl die Frage etwas alt ist.
quelle