Udostępnij przez


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