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

ADO.NET でのトランザクションは、作業の 1 つの単位として実行されるように、複数のタスクをまとめてバインドするときに使用されます。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