Wenn Sie die Fehlermeldung 3902, Ebene 16 erhalten, die lautet:„Die Anfrage COMMIT TRANSACTION hat keine entsprechende BEGIN TRANSACTION“, liegt das wahrscheinlich daran, dass Sie einen verirrten COMMIT
haben Erklärung.
Sie könnten dies erhalten, weil Sie die Fehlerbehandlung implementieren und vergessen, dass Sie die Transaktion bereits an anderer Stelle in Ihrem Code festgeschrieben oder rückgängig gemacht haben.
Fehlerbeispiel
Hier ist ein einfaches Beispiel, um den Fehler zu demonstrieren:
SELECT ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
Ergebnis:
(7 rows affected) Msg 3902, Level 16, State 1, Line 2 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
Dies geschieht, wenn Sie SET IMPLICIT_TRANSACTIONS
ist OFF
. Unten erfahren Sie, was passiert, wenn SET IMPLICIT_TRANSACTIONS
ist ON
.
Beispiel für Fehler aufgrund von Fehlerbehandlung
Sie könnten dies erhalten, weil Sie die Fehlerbehandlung implementieren und vergessen, dass Sie die Transaktion bereits an anderer Stelle in Ihrem Code festgeschrieben oder rückgängig gemacht haben.
Zum Beispiel:
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Orders ( OrderId, OrderDate, CustomerId )
VALUES ( 5006, SYSDATETIME(), 1006 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 1, 1, 20, 25.99 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 2, 7, 120, 9.99 );
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
COMMIT TRANSACTION;
Ergebnis:
(1 row affected) (1 row affected) (1 row affected) Msg 3902, Level 16, State 1, Line 20 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
In diesem Fall hatte ich bereits COMMIT TRANSACTION
im TRY
Block. Also bis zum zweiten COMMIT TRANSACTION
gefunden wurde, wurde die Transaktion bereits festgeschrieben.
Wir würden dasselbe sehen, selbst wenn die Transaktion auf einen Fehler gestoßen wäre und zurückgesetzt wurde. Ein Rollback beendet die Transaktion und daher kein weiteres COMMIT
Angaben sind erforderlich.
Um dieses Problem zu beheben, entfernen wir einfach die letzte COMMIT TRANSACTION
, und der Transaktionscode würde wie folgt aussehen:
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Orders ( OrderId, OrderDate, CustomerId )
VALUES ( 5006, SYSDATETIME(), 1006 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 1, 1, 20, 25.99 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 2, 7, 120, 9.99 );
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
Implizite Transaktionen
Wenn Sie implizite Transaktionen aktiviert haben, erhalten Sie möglicherweise andere Ergebnisse als im ersten Beispiel.
Wenn wir IMPLICIT_TRANSACTIONS
setzen auf ON
, hier ist, was wir bekommen:
SET IMPLICIT_TRANSACTIONS ON;
SELECT ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
Ergebnis:
+---------------------------------+----------------+ | ProductName | ProductPrice | |---------------------------------+----------------| | Left handed screwdriver | 25.99 | | Long Weight (blue) | 14.75 | | Long Weight (green) | 11.99 | | Sledge Hammer | 33.49 | | Chainsaw | 245.00 | | Straw Dog Box | 55.99 | | Bottomless Coffee Mugs (4 Pack) | 9.99 | +---------------------------------+----------------+ (7 rows affected)
Es tritt kein Fehler auf.
Dies liegt daran, dass bestimmte T-SQL-Anweisungen automatisch eine Transaktion starten, wenn sie ausgeführt werden. Es ist, als ob ihnen ein unsichtbares BEGIN TRANSACTION
vorangestellt wäre Erklärung.
Wenn IMPLICIT_TRANSACTIONS
ist OFF
, werden diese Anweisungen automatisch festgeschrieben. Es ist, als würde ihnen eine unsichtbare COMMIT TRANSACTION
folgen Erklärung. In diesem Szenario befindet sich die Transaktion im Autocommit-Modus.
Wenn IMPLICIT_TRANSACTIONS
ist ON
, gibt es keine unsichtbare COMMIT TRANSACTION
Erklärung. Diese Anweisungen werden immer noch durch ein unsichtbares BEGIN TRANSACTION
gestartet , aber sie müssen explizit beendet werden.
Eine implizite Transaktion bleibt in Bearbeitung, bis sie entweder explizit festgeschrieben oder explizit zurückgesetzt wird.
Daher in diesem Beispiel unser Streuner COMMIT TRANSACTION
-Anweisung wurde tatsächlich benötigt, um die implizite Transaktion zu beenden.