문서를 영문으로 보려면 영문 확인란을 선택하세요. 마우스 포인터를 텍스트 위로 이동시켜 팝업 창에서 영문 텍스트를 표시할 수도 있습니다.
번역
영문

현재 트랜잭션 액세스

SQL Server에서 실행되는 CLR(공용 언어 런타임) 코드를 입력하는 시점에 트랜잭션이 활성 상태인 경우 트랜잭션은 System.Transactions.Transaction 클래스를 통해 표시됩니다. Transaction.Current 속성은 현재 트랜잭션에 액세스하는 데 사용됩니다. 대부분의 경우 트랜잭션에 명시적으로 액세스할 필요가 없습니다. 데이터베이스 연결의 경우 ADO.NET에서는 Connection.Open 메서드를 호출할 때 Transaction.Current를 자동으로 검사하고 연결 문자열에서 Enlist 키워드가 false로 설정되지 않은 경우 연결을 트랜잭션에 투명하게 참여시킵니다.

다음 시나리오에서는 Transaction 개체를 직접 사용할 수 있습니다.

  • 자동 참여를 수행하지 않거나 초기화 동안 몇 가지 이유로 참여하지 못한 리소스를 참여시키려는 경우

  • 리소스를 트랜잭션에 명시적으로 참여시키려는 경우

  • 저장 프로시저 또는 함수 내에서 외부 트랜잭션을 종료하려는 경우. 이 경우에는 TransactionScope를 사용합니다. 예를 들어 다음 코드에서는 현재 트랜잭션을 롤백합니다.

    using(TransactionScope transactionScope = new TransactionScope(TransactionScopeOptions.Required)) { }
    

이 항목의 나머지 부분에서는 외부 트랜잭션을 취소하는 다른 방법에 대해 설명합니다.

관리되는 프로시저나 함수에서 다음과 같은 방법으로 외부 트랜잭션을 취소할 수 있습니다.

  • 관리되는 프로시저나 함수에서 출력 매개 변수를 사용하여 값을 반환할 수 있습니다. 호출 Transact-SQL 프로시저는 반환된 값을 검사하고 해당되는 경우 ROLLBACK TRANSACTION을 실행할 수 있습니다.

  • 관리되는 프로시저나 함수에서 사용자 지정 예외를 throw할 수 있습니다. 호출 Transact-SQL 프로시저는 관리되는 프로시저나 함수에서 throw된 예외를 try/catch 블록으로 catch하고 ROLLBACK TRANSACTION을 실행할 수 있습니다.

  • 관리되는 프로시저나 함수에서 특정 조건에 맞는 경우 Transaction.Rollback 메서드를 호출하여 현재 트랜잭션을 취소할 수 있습니다.

관리되는 프로시저나 함수 내에서 호출할 경우 Transaction.Rollback 메서드는 모호한 오류 메시지와 함께 예외를 throw하고 try/catch 블록에 래핑될 수 있습니다. 오류 메시지는 다음과 유사합니다.

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.

이 예외는 예상된 것이며, 코드 실행을 계속하려면 try/catch 블록이 필요합니다. try/catch 블록이 없으면 즉시 예외가 호출 Transact-SQL 프로시저로 throw되고 관리되는 코드 실행이 완료됩니다. 관리되는 코드 실행이 완료되면 다른 예외가 발생합니다.

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.

이 예외도 예상된 것이며 실행을 계속하려면 트리거를 발생시키는 동작을 수행하는 Transact-SQL 문을 try/catch 블록으로 둘러싸야 합니다. 두 가지 예외가 throw되지만 트랜잭션이 롤백되고 변경 내용이 커밋되지 않습니다.

다음은 Transaction.Rollback 메서드를 사용하여 관리되는 프로시저에서 트랜잭션을 롤백하는 예입니다. 관리되는 코드에서 Transaction.Rollback 메서드는 try/catch 블록으로 둘러싸여 있습니다. Transact-SQL 스크립트는 어셈블리 및 관리되는 저장 프로시저를 만듭니다. 관리되는 프로시저 실행이 완료될 때 throw되는 예외가 catch되도록 EXEC uspRollbackFromProc 문이 try/catch 블록에 래핑됩니다.

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

커뮤니티 추가 항목

추가
표시: