Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Dotyczy:programu SQL Server
Jeśli transakcja jest aktywna w momencie, w którym wprowadzono kod środowiska uruchomieniowego języka wspólnego (CLR) uruchomiony w programie SQL Server, transakcja jest uwidoczniona za pośrednictwem klasy System.Transactions.Transaction. Właściwość Transaction.Current służy do uzyskiwania dostępu do bieżącej transakcji. W większości przypadków nie jest konieczne jawne uzyskanie dostępu do transakcji. W przypadku połączeń z bazą danych ADO.NET sprawdza, Transaction.Current automatycznie, gdy wywoływana jest metoda Connection.Open, i w sposób niewidoczny powoduje zarejestrowanie połączenia w tej transakcji (chyba że słowo kluczowe Enlist ma wartość false w parametrach połączenia).
Możesz chcieć użyć obiektu Transaction bezpośrednio w następujących scenariuszach:
Jeśli chcesz zarejestrować zasób, który nie wykonuje automatycznej rejestracji lub z jakiegoś powodu nie został wymieniony podczas inicjowania.
Jeśli chcesz jawnie zarejestrować zasób w transakcji.
Jeśli chcesz zakończyć transakcję zewnętrzną z poziomu procedury składowanej lub funkcji. W tym przypadku użyjesz TransactionScope. Na przykład następujący kod cofa bieżącą transakcję:
using(TransactionScope transactionScope = new TransactionScope(TransactionScopeOptions.Required)) { }
W pozostałej części tego artykułu opisano inne sposoby anulowania transakcji zewnętrznej.
Anulowanie transakcji zewnętrznej
Transakcje zewnętrzne można anulować z poziomu procedury zarządzanej lub funkcji w następujący sposób:
Procedura zarządzana lub funkcja może zwrócić wartość przy użyciu parametru wyjściowego. Procedura wywoływania Transact-SQL może sprawdzić zwróconą wartość i, jeśli jest to konieczne, wykonać
ROLLBACK TRANSACTION.Procedura zarządzana lub funkcja może zgłaszać wyjątek niestandardowy. Procedura wywoływania Transact-SQL może przechwycić wyjątek zgłoszony przez procedurę zarządzaną lub funkcję w bloku try/catch i wykonać
ROLLBACK TRANSACTION.Procedura zarządzana lub funkcja może anulować bieżącą transakcję, wywołując metodę
Transaction.Rollback, jeśli zostanie spełniony określony warunek.
Gdy metoda Transaction.Rollback jest wywoływana w ramach zarządzanej procedury lub funkcji, zgłasza wyjątek z niejednoznacznym komunikatem o błędzie i może zostać opakowany w bloku try/catch. Komunikat o błędzie jest podobny do następujących danych wyjściowych:
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, a blok try/catch jest niezbędny do kontynuowania wykonywania kodu. Bez bloku try/catch wyjątek jest natychmiast zgłaszany do procedury wywoływania Transact-SQL i kończy wykonywanie kodu zarządzanego. Po zakończeniu wykonywania kodu zarządzanego zostanie zgłoszony inny 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.
Ten wyjątek jest również oczekiwany, a wykonanie w celu kontynuowania musi mieć blok try/catch wokół instrukcji Transact-SQL, która wykonuje akcję uruchamiającą wyzwalacz. Pomimo zgłoszonych dwóch wyjątków transakcja jest cofana, a zmiany nie są zatwierdzane.
Przykład
Poniższy kod to przykład transakcji wycofanej z procedury zarządzanej przy użyciu metody Transaction.Rollback. Zwróć uwagę na blok try/catch wokół metody Transaction.Rollback w kodzie zarządzanym. Skrypt Transact-SQL tworzy zestaw i zarządzaną procedurę składowaną. Instrukcja EXEC uspRollbackFromProc jest owinięta w bloku try/catch, tak aby wyjątek zgłaszany podczas wykonywania procedury zarządzanej został przechwycony.
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();
}
}
};
Rejestrowanie i wykonywanie zestawu w Transact-SQL
Zarejestruj zestaw.
CREATE ASSEMBLY TestProcs FROM 'C:\Programming\TestProcs.dll'; GO CREATE PROCEDURE uspRollbackFromProc AS EXTERNAL NAME TestProcs.StoredProcedures.uspRollbackFromProc; GOUruchom procedurę.
BEGIN TRY BEGIN TRANSACTION; -- Perform other actions. EXECUTE 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; PRINT N'Transaction rolled back.'; END CATCH GOCzyszczenie środowiska.
DROP PROCEDURE uspRollbackFromProc; GO DROP ASSEMBLY TestProcs; GO