Zugriff auf die aktuelle Transaktion
Gilt für: SQL Server
Wenn eine Transaktion an dem Punkt aktiv ist, an dem clR-Code (Common Language Runtime) auf SQL Server ausgeführt wird, wird die Transaktion über die System.Transactions.Transaction-Klasse verfügbar gemacht. Mit der Transaction.Current -Eigenschaft wird auf die aktuelle Transaktion zugegriffen. In den meisten Fällen ist es nicht notwendig, explizit auf die Transaktion zuzugreifen. Bei Datenbankverbindungen überprüft ADO.NET Transaction.Current automatisch beim Aufruf der Connection.Open -Methode, und trägt die Verbindung automatisch in diese Transaktion ein (sofern für das Schlüsselwort Enlist in der Verbindungszeichenfolge nicht false angegeben wurde).
In den folgenden Szenarien sollten Sie das Transaction -Objekt direkt verwenden:
Wenn Sie eine Ressource eintragen möchten, die nicht automatisch eingetragen wird oder die aus irgendeinem Grund während der Initialisierung nicht eingetragen wurde.
Wenn Sie eine Ressource explizit in die Transaktion eintragen möchten.
Wenn Sie die externe Transaktion aus einer gespeicherten Prozedur oder Funktion heraus beenden möchten. In diesem Fall verwenden Sie TransactionScope. Beispielsweise wird mit dem folgenden Code die aktuelle Transaktion rückgängig gemacht.
using(TransactionScope transactionScope = new TransactionScope(TransactionScopeOptions.Required)) { }
Im weiteren Verlauf dieses Themas werden andere Möglichkeiten beschrieben, eine externe Transaktion abzubrechen.
Abbrechen einer externen Transaktion
Sie können externe Transaktionen wie folgt von einer verwalteten Prozedur oder einer Funktion aus abbrechen:
Die verwaltete Prozedur oder die Funktion kann in einem Ausgabeparameter einen Wert zurückgeben. Die aufrufende Transact-SQL-Prozedur kann den zurückgegebenen Wert überprüfen und ggf. ROLLBACK TRANSACTION ausführen.
Die verwaltete Prozedur oder die Funktion kann eine benutzerdefinierte Ausnahme auslösen. Die aufrufende Transact-SQL-Prozedur kann die von der verwalteten Prozedur oder Funktion ausgelöste Ausnahme in einem Try/Catch-Block abfangen und ROLLBACK TRANSACTION ausführen.
Die verwaltete Prozedur oder die Funktion kann die aktuelle Transaktion durch einen Aufruf der Transaction.Rollback -Methode abbrechen, wenn eine bestimmte Bedingung erfüllt wird.
Beim Aufruf innerhalb einer verwalteten Prozedur oder Funktion löst die Transaction.Rollback -Methode eine Ausnahme mit einer nicht eindeutigen Fehlermeldung aus und kann in einen try/catch-Block eingebunden werden. Die Fehlermeldung ähnelt folgendem:
Msg 3994, Level 16, State 1, Procedure uspRollbackFromProc, Line 0
Transaction is not allowed to roll back inside a user defined routine, trigger or aggregate because the transaction is not started in that CLR level. Change application logic to enforce strict transaction nesting.
Diese Ausnahme wird erwartet und der try/catch-Block ist notwendig, damit die Codeausführung fortgesetzt wird. Ohne den Try/Catch-Block wird die Ausnahme sofort an die aufrufende Transact-SQL-Prozedur ausgelöst, und die Ausführung von verwaltetem Code wird beendet. Wenn die Ausführung des verwalteten Codes beendet ist, wird eine andere Ausnahme ausgelöst.
Msg 3991, Level 16, State 1, Procedure uspRollbackFromProc, Line 1
The context transaction which was active before entering user defined routine, trigger or aggregate " uspRollbackFromProc " has been ended inside of it, which is not allowed. Change application logic to enforce strict transaction nesting. The statement has been terminated.
Diese Ausnahme wird ebenfalls erwartet, und damit die Ausführung fortgesetzt wird, benötigen Sie einen Try/Catch-Block um die Transact-SQL-Anweisung, die die Aktion ausführt, die den Trigger auslöst. Trotz der zwei ausgelösten Ausnahmen wird ein Rollback für die Transaktion ausgeführt, und für die Änderungen in der Tabelle wird kein Commit ausgeführt.
Beispiel
Im folgenden Beispiel wird von der verwalteten Prozedur für eine Transaktion mit der Transaction.Rollback -Methode ein Rollback für die Transaktion ausgeführt. Beachten Sie den try/catch-Block um die Transaction.Rollback -Methode im verwalteten Code. Das Transact-SQL-Skript erstellt eine Assembly- und verwaltete gespeicherte Prozedur. Beachten Sie, dass die EXEC uspRollbackFromProc -Anweisung in einen try/catch-Block eingebunden ist, sodass die Ausnahme abgefangen wird, die ausgelöst wird, sobald die Ausführung der verwalteten Prozedur beendet wurde.
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Transactions;
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void uspRollbackFromProc()
{
using (SqlConnection connection = new SqlConnection(@"context connection=true"))
{
// Open the connection.
connection.Open();
bool successCondition = true;
// Success condition is met.
if (successCondition)
{
SqlContext.Pipe.Send("Success condition met in procedure.");
// Perform other actions here.
}
// Success condition is not met, the transaction will be rolled back.
else
{
SqlContext.Pipe.Send("Success condition not met in managed procedure. Transaction rolling back...");
try
{
// Get the current transaction and roll it back.
Transaction trans = Transaction.Current;
trans.Rollback();
}
catch (SqlException ex)
{
// Catch the expected exception.
// This allows the connection to close correctly.
}
}
// Close the connection.
connection.Close();
}
}
};
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
Imports System.Transactions
Partial Public Class StoredProcedures
<Microsoft.SqlServer.Server.SqlProcedure()> _
Public Shared Sub uspRollbackFromProc ()
Using connection As New SqlConnection("context connection=true")
' Open the connection.
connection.Open()
Dim successCondition As Boolean
successCondition = False
' Success condition is met.
If successCondition Then
SqlContext.Pipe.Send("Success condition met in procedure.")
' Success condition is not met, the transaction will be rolled back.
Else
SqlContext.Pipe.Send("Success condition not met in managed procedure. Transaction rolling back...")
Try
' Get the current transaction and roll it back.
Dim trans As Transaction
trans = Transaction.Current
trans.Rollback()
Catch ex As SqlException
' Catch the exception instead of throwing it.
' This allows the connection to close correctly.
End Try
End If
' Close the connection.
connection.Close()
End Using
End Sub
End Class
Transact-SQL
--Register assembly.
CREATE ASSEMBLY TestProcs FROM 'C:\Programming\TestProcs.dll'
Go
CREATE PROCEDURE uspRollbackFromProc AS EXTERNAL NAME TestProcs.StoredProcedures.uspRollbackFromProc
Go
-- Execute procedure.
BEGIN TRY
BEGIN TRANSACTION
-- Perform other actions.
Exec uspRollbackFromProc
-- Perform other actions.
PRINT N'Commiting transaction...'
COMMIT TRANSACTION
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrorNum, ERROR_MESSAGE() AS ErrorMessage
PRINT N'Exception thrown, rolling back transaction.'
ROLLBACK TRANSACTION
PRINT N'Transaction rolled back.'
END CATCH
Go
-- Clean up.
DROP Procedure uspRollbackFromProc;
Go
DROP ASSEMBLY TestProcs;
Go
Weitere Informationen
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Tickets als Feedbackmechanismus für Inhalte auslaufen lassen und es durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unter:Einreichen und Feedback anzeigen für