次の方法で共有


現在のトランザクションにアクセスする

適用対象:SQL Server

SQL Server で実行されている共通言語ランタイム (CLR) コードが入力された時点でトランザクションがアクティブな場合、トランザクションは System.Transactions.Transaction クラスを介して公開されます。 Transaction.Current プロパティは、現在のトランザクションにアクセスするために使用されます。 ほとんどの場合、トランザクションに明示的にアクセスする必要はありません。 データベース接続の場合、ADO.NET Transaction.CurrentConnection.Open メソッドが呼び出されたときに自動的にチェックされ、そのトランザクションに透過的に参加します (接続文字列で Enlist キーワードが false に設定されていない場合)。

次のシナリオでは、Transaction オブジェクトを直接使用できます。

  • 自動参加を行わないリソース、または何らかの理由で初期化中に参加しなかったリソースを参加させる場合。

  • リソースを明示的にトランザクションに参加させる場合。

  • ストアド プロシージャまたは関数内から外部トランザクションを終了させる場合。 この場合は、TransactionScope を使用します。 たとえば、次のコードは現在のトランザクションをロールバックします。

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

この記事の残りの部分では、外部トランザクションを取り消す他の方法について説明します。

外部トランザクションを取り消す

外部トランザクションは、次の方法でマネージド プロシージャまたは関数からキャンセルできます。

  • マネージド プロシージャまたは関数は、出力パラメーターを使用して値を返すことができます。 呼び出し元 Transact-SQL プロシージャは、戻り値を確認し、必要に応じて、ROLLBACK TRANSACTION実行できます。

  • マネージド プロシージャまたは関数は、カスタムの例外をスローできます。 呼び出し元 Transact-SQL プロシージャは、try/catch ブロック内のマネージド プロシージャまたは関数によってスローされた例外をキャッチし、ROLLBACK TRANSACTION実行できます。

  • マネージド プロシージャまたは関数は、特定の条件が満たされた場合に Transaction.Rollback メソッドを呼び出すことによって、現在のトランザクションを取り消すことができます。

Transaction.Rollback メソッドは、マネージド プロシージャまたは関数内で呼び出されると、あいまいなエラー メッセージを含む例外をスローし、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 プロシージャに例外が直ちにスローされ、マネージド コードの実行が完了します。 マネージド コードが実行を終了すると、別の例外が発生します。

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 ブロックが必要です。 2 つの例外がスローされたにもかかわらず、トランザクションはロールバックされ、変更はコミットされません。

次のコードは、Transaction.Rollback メソッドを使用してマネージド プロシージャからロールバックされるトランザクションの例です。 マネージド コード内の Transaction.Rollback メソッドの周囲に try/catch ブロックがあることに注意してください。 Transact-SQL スクリプトは、アセンブリとマネージド ストアド プロシージャを作成します。 EXEC uspRollbackFromProc ステートメントは try/catch ブロックにラップされるため、マネージド プロシージャの実行が完了したときにスローされる例外がキャッチされます。

  • C# を する
  • Visual Basic .NET の
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();
   }
}
};

Transact-SQL でアセンブリを登録して実行する

  1. アセンブリを登録します。

    CREATE ASSEMBLY TestProcs
        FROM 'C:\Programming\TestProcs.dll';
    GO
    
    CREATE PROCEDURE uspRollbackFromProc
    AS EXTERNAL NAME TestProcs.StoredProcedures.uspRollbackFromProc;
    GO
    
  2. プロシージャを実行します。

    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
    GO
    
  3. 環境をクリーンアップします。

    DROP PROCEDURE uspRollbackFromProc;
    GO
    
    DROP ASSEMBLY TestProcs;
    GO
    
  • CLR の統合とトランザクションの を する