Uzyskiwanie dostępu do bieżącej transakcji
Jeśli transakcja jest aktywny w miejscu, w których wykonywalnych języka wspólnego (CLR) kod uruchomionych na SQL Server jest wprowadzony, transakcja jest dostępny za pośrednictwem System.Transactions.Transaction Klasa. The Transaction.Current właściwość is used to access the current transaction. W większości przypadków nie jest konieczne jawnie dostępu transakcji.Dla połączenia z bazą danych ADO.NET sprawdza Transaction.Current automatycznie, gdy Connection.Open Metoda jest nazywana i przezroczysty uzyskuje połączenie w tej transakcji (chyba że Enlist słowo kluczowe jest ustawiona na wartość false w ciąg połączenia).
Warto użyć Transaction obiekt bezpośrednio w następujących scenariuszach:
Jeśli chcesz zarejestrować zasób, który nie działa automatyczne rejestracji lub które jakiegoś powodu nie została zarejestrowana podczas inicjowania.
Jeśli chcesz jawnie zarejestrować zasób w transakcji.
Jeśli chcesz zakończyć transakcję zewnętrzną z wewnątrz sieci procedura przechowywana lub funkcja.W takim przypadek należy używać TransactionScope. Na przykład następujący kod zostanie wycofywania dla bieżącej transakcji:
using(TransactionScope transactionScope = new TransactionScope(TransactionScopeOptions.Required)) { }
Pozostałych w tym temacie opisano inne sposoby anulować transakcję zewnętrznych.
Anulowanie transakcję zewnętrzne
Można anulować transakcje zewnętrzne z zarządzanych procedury lub funkcja w następujący sposób:
Zarządzane procedura lub funkcja może zwracać wartość za pomocą parametru wyjściowego.Wywołujący Transact-SQL Procedura może sprawdzić zwrócona wartość i, w razie potrzeby wykonać ROLLBACK TRANSACTION.
Zarządzane procedura lub funkcja może Zgłoś wyjątek niestandardowych.Wywołujący Transact-SQL Procedura może przechwycić tego wyjątku wygenerowanych przez zarządzane procedury lub funkcja w blok try/catch i wykonać ROLLBACK TRANSACTION.
Zarządzane procedura lub funkcja może anulować bieżącej transakcji poprzez wywołanie Transaction.Rollback Metoda, jeśli określony warunek jest spełniony.
Gdy zostanie wywołana w zarządzanych procedura lub funkcja, Transaction.Rollback Metoda zgłasza wyjątek komunikat o błędzie niejednoznaczne i może być zawijany w blok try/catch. Błąd wiadomości thresembles podobny do następującego:
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.
Ten wyjątek jest oczekiwany i blok try/catch jest konieczne wykonywanie kodu kontynuować.Bez blok try/catch wyjątek będzie się natychmiast zgłoszony do wywołujący Transact-SQL Procedura i wykonywania kod zarządzany zostanie zakończone. Po zakończeniu wykonywania kod zarządzany innego jest wyjątek:
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.
Oczekiwany jest również ten wyjątek i wykonywanie kontynuować, musisz mieć blok try/catch wokół Transact-SQL instrukcja wykonuje akcja, która uruchomieniu wyzwalacza. Pomimo dwa wyjątki generowane, transakcja jest cofana i wprowadzone zmiany nie są zatwierdzone.
Przykład
Oto przykład transakcji jest przywracana z procedury zarządzane przy użyciu Transaction.Rollback Metoda. Należy zauważyć, blok try/catch wokół Transaction.Rollback Metoda w kod zarządzany. The Transact-SQL script creates an wirtualny plik dziennika and managed procedura przechowywana. Należy pamiętać, że EXEC uspRollbackFromProc Instrukcja jest otoczona blok try/catch tak, aby wpadł wyjątek, wyjątek podczas zarządzanej procedura kończy wykonywanie.
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