ローカル トランザクションLocal Transactions

ADO.NET でのトランザクションは、複数のタスクをバインドして単一の作業単位として実行する場合に使用します。Transactions in ADO.NET are used when you want to bind multiple tasks together so that they execute as a single unit of work. たとえば、あるアプリケーションが 2 つのタスクを実行するものとします。For example, imagine that an application performs two tasks. まず、注文情報に従ってテーブルが更新されます。First, it updates a table with order information. 次に、在庫情報を含むテーブルが更新され、注文品の金額が借方記入されます。Second, it updates a table that contains inventory information, debiting the items ordered. いずれかのタスクが失敗すると、両方の更新がロールバックされます。If either task fails, then both updates are rolled back.

トランザクションの種類の判別Determining the Transaction Type

トランザクションは、単一フェーズであり、データベースによって直接処理される場合、ローカル トランザクションと見なされます。A transaction is considered to be a local transaction when it is a single-phase transaction and is handled by the database directly. トランザクション モニターによって調整され、トランザクションの解決にフェール セーフ機構 (2 フェーズのコミットなど) が使用されているトランザクションは、分散トランザクションと見なされます。A transaction is considered to be a distributed transaction when it is coordinated by a transaction monitor and uses fail-safe mechanisms (such as two-phase commit) for transaction resolution.

各 .NET Framework データ プロバイダーには、ローカル トランザクションを実行するための独自の Transaction オブジェクトがあります。Each of the .NET Framework data providers has its own Transaction object for performing local transactions. トランザクションを SQL Server データベースで実行できるようにする場合は、System.Data.SqlClient トランザクションを選択します。If you require a transaction to be performed in a SQL Server database, select a System.Data.SqlClient transaction. Oracle トランザクションの場合は、System.Data.OracleClient プロバイダーを使用します。For an Oracle transaction, use the System.Data.OracleClient provider. さらに、トランザクションを必要とする、プロバイダーに依存しないコードを記述するための DbTransaction クラスもあります。In addition, there is a DbTransaction class that is available for writing provider-independent code that requires transactions.

注意

トランザクションは、サーバー上で実行するのが最も効率的です。Transactions are most efficient when they are performed on the server. 明示的なトランザクションを広範に使用する SQL Server データベースを操作する場合は、Transact-SQL の BEGIN TRANSACTION ステートメントを使用して、ストアド プロシージャとしてトランザクション処理を記述するとよいでしょう。If you are working with a SQL Server database that makes extensive use of explicit transactions, consider writing them as stored procedures using the Transact-SQL BEGIN TRANSACTION statement.

単一の接続を使用したトランザクションの実行Performing a Transaction Using a Single Connection

ADO.NET では、Connection オブジェクトを使用してトランザクションを制御します。In ADO.NET, you control transactions with the Connection object. ローカル トランザクションは、BeginTransaction メソッドを使用して開始できます。You can initiate a local transaction with the BeginTransaction method. トランザクションを開始すると、Transaction オブジェクトの Command プロパティを使用して、そのトランザクションにコマンドを参加させることができます。Once you have begun a transaction, you can enlist a command in that transaction with the Transaction property of a Command object. 次に、トランザクションの内容が成功したか失敗したかに基づいて、データ ソースに対する変更をコミットまたはロールバックします。You can then commit or roll back modifications made at the data source based on the success or failure of the components of the transaction.

注意

EnlistDistributedTransaction メソッドをローカル トランザクションで使用することはできません。The EnlistDistributedTransaction method should not be used for a local transaction.

トランザクションのスコープは、接続に限定されています。The scope of the transaction is limited to the connection. 次の例では、try ブロック内の 2 つの個別のコマンドで構成される明示的なトランザクションを実行しています。The following example performs an explicit transaction that consists of two separate commands in the try block. これらのコマンドでは、SQL Server の AdventureWorks サンプル データベース内の Production.ScrapReason テーブルに対して INSERT ステートメントが実行され、例外がスローされない場合はコミットされます。The commands execute INSERT statements against the Production.ScrapReason table in the AdventureWorks SQL Server sample database, which are committed if no exceptions are thrown. catch ブロック内のコードは、例外がスローされた場合にトランザクションをロールバックします。The code in the catch block rolls back the transaction if an exception is thrown. トランザクションが完了する前に中止されるか接続が終了すると、トランザクションは自動的にロールバックされます。If the transaction is aborted or the connection is closed before the transaction has completed, it is automatically rolled back.

Example

トランザクションを実行するには、次の手順に従います。Follow these steps to perform a transaction.

  1. BeginTransaction オブジェクトの SqlConnection メソッドを呼び出して、トランザクションの開始位置をマークします。Call the BeginTransaction method of the SqlConnection object to mark the start of the transaction. BeginTransaction メソッドは、トランザクションへの参照を返します。The BeginTransaction method returns a reference to the transaction. この参照は、トランザクションに参加する SqlCommand オブジェクトに割り当てられます。This reference is assigned to the SqlCommand objects that are enlisted in the transaction.

  2. 実行する TransactionTransaction プロパティに、SqlCommand オブジェクトを割り当てます。Assign the Transaction object to the Transaction property of the SqlCommand to be executed. アクティブなトランザクションを持つ接続上でコマンドが実行され、Transaction オブジェクトの Transaction プロパティに Command オブジェクトが割り当てられていない場合は、例外がスローされます。If a command is executed on a connection with an active transaction, and the Transaction object has not been assigned to the Transaction property of the Command object, an exception is thrown.

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

  4. Commit オブジェクトの SqlTransaction メソッドを呼び出してトランザクションを完了するか、Rollback メソッドを呼び出してトランザクションを終了します。Call the Commit method of the SqlTransaction object to complete the transaction, or call the Rollback method to end the transaction. Commit または Rollback メソッドが実行される前に接続が終了または破棄されると、トランザクションはロールバックされます。If the connection is closed or disposed before either the Commit or Rollback methods have been executed, the transaction is rolled back.

次のコード サンプルでは、Microsoft SQL Server で ADO.NET を使用するトランザクション ロジックを示します。The following code example demonstrates transactional logic using ADO.NET with Microsoft SQL Server.

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);
        }
    }
}
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

関連項目See also