適用対象:SQL Server
SQL Server で実行されている共通言語ランタイム (CLR) コードが入力された時点でトランザクションがアクティブな場合、トランザクションは System.Transactions.Transaction
クラスを介して公開されます。
Transaction.Current
プロパティは、現在のトランザクションにアクセスするために使用されます。 ほとんどの場合、トランザクションに明示的にアクセスする必要はありません。 データベース接続の場合、ADO.NET Transaction.Current
Connection.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 でアセンブリを登録して実行する
アセンブリを登録します。
CREATE ASSEMBLY TestProcs FROM 'C:\Programming\TestProcs.dll'; GO CREATE PROCEDURE uspRollbackFromProc AS EXTERNAL NAME TestProcs.StoredProcedures.uspRollbackFromProc; GO
プロシージャを実行します。
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
環境をクリーンアップします。
DROP PROCEDURE uspRollbackFromProc; GO DROP ASSEMBLY TestProcs; GO
関連コンテンツ
- CLR の統合とトランザクションの を
する