Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie implizite Transaktionen in SQL Server funktionieren

Es gibt vier Transaktionsmodi in SQL Server. Einer davon ist der implizite Modus.

In SQL Server ist eine implizite Transaktion, wenn eine neue Transaktion implizit gestartet wird, wenn die vorherige Transaktion abgeschlossen ist, aber jede Transaktion explizit mit einem COMMIT abgeschlossen wird oder ROLLBACK Aussage.

Dies ist nicht mit dem Autocommit-Modus zu verwechseln, bei dem die Transaktion implizit gestartet und beendet wird.

Die vier Transaktionsmodi

SQL Server kann in den folgenden Transaktionsmodi betrieben werden:

Transaktionsmodus Beschreibung
Autocommit-Transaktion Jeder einzelne Auszug ist eine Transaktion.
Implizite Transaktion Eine neue Transaktion wird implizit gestartet, wenn die vorherige Transaktion abgeschlossen ist, aber jede Transaktion wird explizit abgeschlossen, typischerweise mit einem COMMIT oder ROLLBACK Anweisung je nach DBMS.
Explizite Transaktion Explizit gestartet mit einer Zeile wie START TRANSACTION , BEGIN TRANSACTION oder ähnliches, abhängig vom DBMS, und mit den entsprechenden Anweisungen explizit festgeschrieben oder zurückgesetzt.
Batch-bezogene Transaktion Gilt nur für mehrere aktive Ergebnissätze (MARS). Eine explizite oder implizite Transaktion, die unter einer MARS-Sitzung beginnt, wird zu einer Batch-bezogenen Transaktion.

Impliziter Modus vs. Autocommit

In SQL Server starten bestimmte Anweisungen automatisch eine Transaktion, wenn sie ausgeführt werden. Es ist, als ob ihnen ein unsichtbares BEGIN TRANSACTION vorangestellt wäre Aussage.

In den meisten Fällen werden diese Transaktionen auch implizit festgeschrieben, als gäbe es eine unsichtbare COMMIT TRANSACTION Erklärung. Solche Transaktionen befinden sich im Autocommit-Modus .

In anderen Fällen gibt es keine unsichtbare COMMIT TRANSACTION passend zum unsichtbaren BEGIN TRANSACTION Erklärung. Die Transaktion bleibt in Bearbeitung, bis Sie sie explizit festschreiben oder mit COMMIT TRANSACTION rückgängig machen oder ROLLBACK TRANSACTION Erklärung. In diesem Fall befindet sich die Transaktion im impliziten Modus .

Ob die Transaktion im impliziten Modus oder im Autocommit-Modus ausgeführt wird, hängt von Ihren IMPLICIT_TRANSACTIONS ab Einstellung.

Anweisungen, die eine implizite Transaktion starten

Die folgenden Anweisungen starten eine implizite Transaktion in SQL Server.

  • ALTER TABLE
  • BEGIN TRANSACTION
  • CREATE
  • DELETE
  • DROP
  • FETCH
  • GRANT
  • INSERT
  • OPEN
  • REVOKE
  • SELECT (außer denen, die nicht aus einer Tabelle auswählen, wie z. B. SELECT GETDATE() oder SELECT 1*1 )
  • TRUNCATE TABLE
  • UPDATE

Jedes Mal, wenn Sie diese T-SQL-Anweisungen ausführen, starten Sie eine Transaktion. Meistens wird die Transaktion automatisch festgeschrieben. Sie haben also die Transaktion gestartet und beendet, ohne dies ausdrücklich tun zu müssen.

Allerdings abhängig von Ihren IMPLICIT_TRANSACTIONS müssen Sie die Transaktion möglicherweise explizit festschreiben.

Wenn IMPLICIT_TRANSACTIONS ist OFF

Wenn Ihre IMPLICIT_TRANSACTIONS Einstellung ist OFF , führen die obigen Anweisungen Transaktionen im Autocommit-Modus aus. Das heißt, sie beginnen mit und beendet die Transaktion implizit.

Es ist also wie eine unsichtbare BEGIN TRANSACTION -Anweisung und eine unsichtbare COMMIT TRANSACTION Anweisung, alles aus einer Anweisung.

In diesem Fall müssen Sie nichts tun, um die Transaktion festzuschreiben oder rückgängig zu machen. Es wurde bereits für Sie erledigt.

Wenn IMPLICIT_TRANSACTIONS ist ON

Wenn Ihre IMPLICIT_TRANSACTIONS Einstellung ist ON , verhalten sich die obigen Anweisungen etwas anders.

Wenn IMPLICIT_TRANSACTIONS Einstellung ist ON , erhalten die obigen Anweisungen ein unsichtbares BEGIN TRANSACTION -Anweisung, aber sie erhalten keine entsprechende COMMIT TRANSACTION Aussage.

Das bedeutet, dass Sie die Transaktion selbst explizit festschreiben oder rückgängig machen müssen.

Wenn der Transaktionsmodus jedoch implizit ist, kein unsichtbares BEGIN TRANSACTION wird ausgegeben, wenn eine Transaktion bereits im Gange ist.

Beispiel

Hier ist ein Beispiel, um das Konzept zu demonstrieren.

SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS OFF;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;

Ergebnis:

+--------------------+
| TransactionCount   |
|--------------------|
| 0                  |
+--------------------+
(1 row affected)
Commands completed successfully.
+-------------------------+----------------+
| ProductName             | ProductPrice   |
|-------------------------+----------------|
| Left handed screwdriver | 25.99          |
+-------------------------+----------------+
(1 row affected)
+--------------------+
| TransactionCount   |
|--------------------|
| 0                  |
+--------------------+
(1 row affected)

In diesem Fall setze ich IMPLICIT_TRANSACTIONS auf OFF und führen Sie SELECT aus Erklärung. Das bedeutete, dass die SELECT -Anweisung wurde im Autocommit-Modus ausgeführt, und daher wurde die Transaktion implizit gestartet und beendet.

@@TRANCOUNT gab 0 zurück , was bedeutet, dass zu diesem Zeitpunkt keine Transaktionen ausgeführt wurden.

Hier ist es wieder, außer dass wir dieses Mal IMPLICIT_TRANSACTIONS setzen auf ON .

SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;

Ergebnis:

+--------------------+
| TransactionCount   |
|--------------------|
| 0                  |
+--------------------+
(1 row affected)
Commands completed successfully.
+-------------------------+----------------+
| ProductName             | ProductPrice   |
|-------------------------+----------------|
| Left handed screwdriver | 25.99          |
+-------------------------+----------------+
(1 row affected)
+--------------------+
| TransactionCount   |
|--------------------|
| 1                  |
+--------------------+
(1 row affected)

Der letzte @@TRANCOUNT gibt einen Wert von 1 zurück . Das bedeutet, dass unsere Transaktion noch im Gange ist.

@@TRANCOUNT gibt die Nummer von BEGIN TRANSACTION zurück Anweisungen, die bei der aktuellen Verbindung aufgetreten sind. Wir haben keine explizit ausgestellt, aber eine wurde implizit ausgestellt.

Also müssen wir diese Transaktion tatsächlich festschreiben (oder rückgängig machen), um den @@TRANCOUNT zu dekrementieren bis 0 .

COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;

Ergebnis:

+--------------------+
| TransactionCount   |
|--------------------|
| 0                  |
+--------------------+
(1 row affected)

Der Code für unsere implizite Transaktion sollte also den COMMIT enthalten Aussage:

SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;

Ergebnis:

+--------------------+
| TransactionCount   |
|--------------------|
| 0                  |
+--------------------+
(1 row affected)
Commands completed successfully.
+-------------------------+----------------+
| ProductName             | ProductPrice   |
|-------------------------+----------------|
| Left handed screwdriver | 25.99          |
+-------------------------+----------------+
(1 row affected)
Commands completed successfully.
+--------------------+
| TransactionCount   |
|--------------------|
| 0                  |
+--------------------+
(1 row affected)

ANSI_DEFAULTS

Wenn Sie feststellen, dass implizite Transaktionen unerwartet aktiviert werden, könnte dies an ANSI_DEFAULTS liegen Einstellung.