次の方法で共有


ローカル トランザクション (ADO.NET)

更新 : November 2007

ADO.NET でのトランザクションは、複数のタスクをバインドして単一の作業単位として実行する場合に使用します。たとえば、あるアプリケーションが 2 つのタスクを実行するとします。まず、注文情報に従ってテーブルが更新されます。次に、在庫情報を含むテーブルが更新され、注文品の金額が借方記入されます。いずれかのタスクが失敗すると、両方の更新がロールバックされます。

トランザクションの種類の判別

単一フェーズであり、データベースによって直接処理されるトランザクションは、ローカル トランザクションであると見なされます。トランザクション モニタによってコーディネートされ、トランザクションの解決にフェール セーフ機構 (2 フェーズのコミットなど) を使用しているトランザクションは、分散トランザクションであると見なされます。

.NET Framework データ プロバイダは、それぞれ独自の Transaction オブジェクトを使用してローカル トランザクションを実行しています。トランザクションを SQL Server データベースで実行できるようにする場合は、System.Data.SqlClient トランザクションを選択します。Oracle トランザクションの場合は、System.Data.OracleClient プロバイダを使用します。さらに、トランザクションを必要とする、プロバイダに依存しないコードを記述するための新しい DbTransaction クラスもあります。

2k2hy99x.alert_note(ja-jp,VS.90).gifメモ :

トランザクションは、サーバー上で実行するのが最も効率的です。明示的なトランザクションを広範に使用する SQL Server データベースを操作する場合は、Transact-SQL の BEGIN TRANSACTION ステートメントを使用して、ストアド プロシージャとしてトランザクション処理を記述するとよいでしょう。サーバー側のトランザクション実行の詳細については、SQL Server オンライン ブックを参照してください。

単一の接続を使用したトランザクションの実行

ADO.NET では、Connection オブジェクトを使用してトランザクションを制御します。ローカル トランザクションは、BeginTransaction メソッドを使用して開始できます。トランザクションを開始すると、Command オブジェクトの Transaction プロパティを使用して、そのトランザクションにコマンドを参加させることができます。次に、トランザクションの内容が成功したか失敗したかに基づいて、データ ソースに対する変更をコミットまたはロールバックします。

2k2hy99x.alert_note(ja-jp,VS.90).gifメモ :

EnlistDistributedTransaction メソッドをローカル トランザクションで使用することはできません。

トランザクションのスコープは、接続に限定されています。次の例では、try ブロック内の 2 つの個別のコマンドで構成される明示的なトランザクションを実行しています。これらのコマンドは、SQL Server 2005 の AdventureWorks サンプル データベース内の Production.ScrapReason テーブルに対して INSERT ステートメントを実行し、例外がスローされない場合にコミットします。catch ブロック内のコードは、例外がスローされた場合にトランザクションをロールバックします。トランザクションが完了する前に中止されるか接続が終了すると、トランザクションは自動的にロールバックされます。

トランザクションを実行するには、次の手順に従います。

  1. SqlConnection オブジェクトの BeginTransaction メソッドを呼び出して、トランザクションの開始位置をマークします。BeginTransaction メソッドは、トランザクションへの参照を返します。この参照は、トランザクションに参加する SqlCommand オブジェクトに割り当てられます。

  2. 実行する SqlCommandTransaction プロパティに、Transaction オブジェクトを割り当てます。アクティブなトランザクションを持つ接続上でコマンドが実行され、Command オブジェクトの Transaction プロパティに Transaction オブジェクトが割り当てられていない場合は、例外がスローされます。

  3. 必要なコマンドを実行します。

  4. SqlTransaction オブジェクトの Commit メソッドを呼び出してトランザクションを完了するか、Rollback メソッドを呼び出してトランザクションを終了します。Commit または Rollback メソッドが実行される前に接続が終了または破棄されると、トランザクションはロールバックされます。

Microsoft SQL Server で ADO.NET を使用するトランザクション ロジックを次のコード サンプルに示します。

Using connection As New SqlConnection(connectionString)
    connection.Open()

    ' Start a local transaction.
    Dim sqlTran As SqlTransaction = connection.BeginTransaction()

    ' Enlist a command in the current transaction.
    Dim command As SqlCommand = connection.CreateCommand()
    command.Transaction = sqlTran

    Try
        ' Execute two separate commands.
        command.CommandText = _
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')"
        command.ExecuteNonQuery()
        command.CommandText = _
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')"
        command.ExecuteNonQuery()

        ' Commit the transaction
        sqlTran.Commit()
        Console.WriteLine("Both records were written to database.")

    Catch ex As Exception
        ' Handle the exception if the transaction fails to commit.
        Console.WriteLine(ex.Message)

        Try
            ' Attempt to roll back the transaction.
            sqlTran.Rollback()

        Catch exRollback As Exception
            ' Throws an InvalidOperationException if the connection 
            ' is closed or the transaction has already been rolled 
            ' back on the server.
            Console.WriteLine(exRollback.Message)
        End Try
    End Try
End Using
using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();

    // Start a local transaction.
    SqlTransaction sqlTran = connection.BeginTransaction();

    // Enlist a command in the current transaction.
    SqlCommand command = connection.CreateCommand();
    command.Transaction = sqlTran;

    try
    {
        // Execute two separate commands.
        command.CommandText =
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')";
        command.ExecuteNonQuery();
        command.CommandText =
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')";
        command.ExecuteNonQuery();

        // Commit the transaction.
        sqlTran.Commit();
        Console.WriteLine("Both records were written to database.");
    }
    catch (Exception ex)
    {
        // Handle the exception if the transaction fails to commit.
        Console.WriteLine(ex.Message);

        try
        {
            // Attempt to roll back the transaction.
            sqlTran.Rollback();
        }
        catch (Exception exRollback)
        {
            // Throws an InvalidOperationException if the connection 
            // is closed or the transaction has already been rolled 
            // back on the server.
            Console.WriteLine(exRollback.Message);
        }
    }
}

参照

概念

分散トランザクション (ADO.NET)

SQL Server と System.Transactions の統合 (ADO.NET)

その他の技術情報

トランザクションと同時実行 (ADO.NET)