System.Transactions の使用
適用対象: SQL Server
System.Transactions 名前空間は、ADO.NET および SQL Server 共通言語ランタイム (CLR) 統合と完全に統合されたトランザクション フレームワークを提供します。 System.Transactions.TransactionScope クラスは、分散トランザクションに接続を暗黙的に参加させることで、コード ブロックをトランザクションにします。 TransactionScope でマークされたコード ブロックの末尾で、Complete メソッドを呼び出す必要があります。 Dispose メソッドは、プログラムの実行がコード ブロックから離れると呼び出され、Complete メソッドが呼び出されない場合にトランザクションが中止されます。 コードがスコープから離れるような例外がスローされると、このトランザクションは中止されたと見なされます。
using ブロックを使用して、using ブロックが終了したときに TransactionScope オブジェクトで Dispose メソッドが呼び出されるようにすることをお勧めします。 保留中のトランザクションをコミットまたはロールバックできないと、 TransactionScope の既定のタイムアウトが 1 分であるため、パフォーマンスが大幅に低下する可能性があります。 using ステートメントを使用しない場合は、すべての作業を Try ブロックで実行し、Finally ブロックで Dispose メソッドを明示的に呼び出す必要があります。
TransactionScope内で例外が発生した場合、トランザクションは不整合としてマークされ、破棄されます。 TransactionScope が破棄されるとロールバックされます。 例外が発生しない場合は、参加しているトランザクションがコミットされます。
TransactionScope は、ローカルおよびリモートのデータ ソースまたは外部リソース マネージャーにアクセスする場合にのみ使用する必要があります。 これは、コンテキスト接続内でのみ使用されている場合でもTransactionScopeによってトランザクションが昇格されるためです。
Note
TransactionScope クラスは、既定で System.Transactions.Transaction.IsolationLevel Serializable を使用してトランザクションを作成します。 使用しているアプリケーションによっては、アプリケーション内での競合を回避するために、分離レベルを低下させる必要がある場合があります。
Note
リモート サーバーに対する分散トランザクション内では、大量のデータベース リソースが消費されるため、更新、挿入、および削除だけを実行することをお勧めします。 操作がローカル サーバーで実行される場合は、分散トランザクションは必要なく、ローカル トランザクションで十分です。 SELECT ステートメントは、不必要にデータベース リソースをロックすることがあります。また、選択に多くのトランザクションを要する場合もあります。 データベース以外の作業は、トランザクション処理を行う他のリソース マネージャーを必要とする場合を除き、トランザクションのスコープ外で行う必要があります。 トランザクションのスコープ内の例外によってトランザクションのコミットが妨げられますが、 TransactionScope クラスには、コードがトランザクション自体のスコープ外で行った変更をロールバックするためのプロビジョニングはありません。 トランザクションのロールバック時に何らかのアクションを実行する必要がある場合は、 System.Transactions.IEnlistmentNotification インターフェイスの独自の実装を記述し、トランザクションに明示的に参加させる必要があります。
例
System.Transactions を操作するには、System.Transactions.dll ファイルへの参照が必要です。
次のコードは、SQL Server の 2 つの異なるインスタンスに対して昇格できるトランザクションを作成する方法を示しています。 これらのインスタンスは、TransactionScope ブロックにラップされた 2 つの異なるSystem.Data.SqlClient.SqlConnection オブジェクトによって表されます。 このコードは、using ステートメントを使用して TransactionScope ブロックを作成し、最初の接続を開き、TransactionScope に自動的に参加させます。 このトランザクションは、完全な分散トランザクションとしてではなく、最初に軽量のトランザクションとして参加します。 このコードでは、条件ロジックが存在することを前提としています (説明を簡単にするために、このロジックは省略しています)。 必要な場合にのみ 2 つ目の接続が開き、 TransactionScope に参加します。 2 番目の接続が開かれると、トランザクションは完全な分散トランザクションに自動的に昇格します。 次に、トランザクションをコミットする TransactionScope.Complete を呼び出します。 このコードは、接続の using ステートメントを終了するときに、2 つの接続を破棄します。 TransactionScope の TransactionScope.Dispose メソッドは、TransactionScope の using ブロックの終了時に自動的に呼び出されます。 TransactionScope ブロック内の任意の時点で例外がスローされた場合、Complete は呼び出されず、分散トランザクションは TransactionScope が破棄されたときにロールバックされます。
Visual Basic
Using transScope As New TransactionScope()
Using connection1 As New SqlConnection(connectString1)
' Opening connection1 automatically enlists it in the
' TransactionScope as a lightweight transaction.
connection1.Open()
' Do work in the first connection.
' Assumes conditional logic in place where the second
' connection will only be opened as needed.
Using connection2 As New SqlConnection(connectString2)
' Open the second connection, which enlists the
' second connection and promotes the transaction to
' a full distributed transaction.
connection2.Open()
' Do work in the second connection.
End Using
End Using
' Commit the transaction.
transScope.Complete()
End Using
C#
using (TransactionScope transScope = new TransactionScope())
{
using (SqlConnection connection1 = new
SqlConnection(connectString1))
{
// Opening connection1 automatically enlists it in the
// TransactionScope as a lightweight transaction.
connection1.Open();
// Do work in the first connection.
// Assumes conditional logic in place where the second
// connection will only be opened as needed.
using (SqlConnection connection2 = new
SqlConnection(connectString2))
{
// Open the second connection, which enlists the
// second connection and promotes the transaction to
// a full distributed transaction.
connection2.Open();
// Do work in the second connection.
}
}
// The Complete method commits the transaction.
transScope.Complete();
}