分散トランザクションDistributed Transactions

トランザクションとは、たとえば、1 つの単位として成功 (コミット) または失敗 (アボート) する関連タスク セットです。A transaction is a set of related tasks that either succeeds (commit) or fails (abort) as a unit, among other things. 分散トランザクションは、複数のリソースに影響を与えるトランザクションです。A distributed transaction is a transaction that affects several resources. 分散トランザクションがコミットされるためには、すべての参加要素が、すべてのデータ変更が永久的な変更となることを保証する必要があります。For a distributed transaction to commit, all participants must guarantee that any change to data will be permanent. システム クラッシュその他の予期しない出来事が発生した場合でも、変更は保持されます。Changes must persist despite system crashes or other unforeseen events. 1 つの参加要素がこの保証に失敗しただけでも、トランザクション全体が失敗し、トランザクションのスコープ内のデータに対する変更がロールバックされます。If even a single participant fails to make this guarantee, the entire transaction fails, and any changes to data within the scope of the transaction are rolled back.

注意

トランザクションがアクティブであるときに DataReader が開始された場合、トランザクションをコミットまたはロールバックしようとすると例外がスローされます。An exception will be thrown if you attempt to commit or roll back a transaction if a DataReader is started while the transaction is active.

System.Transactions の操作Working with System.Transactions

.NET Framework では、分散トランザクションは System.Transactions 名前空間内の API を介して管理されます。In the .NET Framework, distributed transactions are managed through the API in the System.Transactions namespace. 複数の永続的なリソース マネージャーが関係する場合、System.Transactions API は分散トランザクション処理を Microsoft Distributed Transaction Coordinator (MS DTC) などのトランザクション モニターに委任します。The System.Transactions API will delegate distributed transaction handling to a transaction monitor such as the Microsoft Distributed Transaction Coordinator (MS DTC) when multiple persistent resource managers are involved. 詳細については、「トランザクションの基礎」を参照してください。For more information, see Transaction Fundamentals.

ADO.NET 2.0 では、EnlistTransaction メソッドを使用した分散トランザクションへの参加のサポートが導入されました。これにより、接続を Transaction インスタンスに参加させることができます。ADO.NET 2.0 introduced support for enlisting in a distributed transaction using the EnlistTransaction method, which enlists a connection in a Transaction instance. ADO.NET の以前のバージョンでは、分散トランザクションへの明示的な参加は、接続の EnlistDistributedTransaction メソッドを使用して実行されていました。これによって ITransaction インスタンス内の接続を参加させることで、下位互換性を得ることができます。In previous versions of ADO.NET, explicit enlistment in distributed transactions was performed using the EnlistDistributedTransaction method of a connection to enlist a connection in a ITransaction instance, which is supported for backwards compatibility. エンタープライズサービストランザクションの詳細については、「エンタープライズサービスと COM + トランザクションの相互運用性」を参照してください。For more information on Enterprise Services transactions, see Interoperability with Enterprise Services and COM+ Transactions.

.NET Framework Provider for SQL Server で SQL Server データベースに対して System.Transactions トランザクションを使用する場合は、軽量な Transaction が自動的に使用されます。When using a System.Transactions transaction with the .NET Framework Provider for SQL Server against a SQL Server database, a lightweight Transaction will automatically be used. トランザクションは、必要に応じて完全な分散トランザクションに昇格させることができます。The transaction can then be promoted to a full distributed transaction on an as-needed basis. 詳細については、「 SQL Server とのシステムトランザクションの統合」を参照してください。For more information, see System.Transactions Integration with SQL Server.

注意

既定では、1 つの Oracle データベースが一度に参加できる分散トランザクションの最大数は 10 に設定されています。The maximum number of distributed transactions that an Oracle database can participate in at one time is set to 10 by default. Oracle データベースに接続している場合、トランザクション数が 10 個を超えると例外がスローされます。After the 10th transaction when connected to an Oracle database, an exception is thrown. Oracle では、分散トランザクション内での DDL はサポートされません。Oracle does not support DDL inside of a distributed transaction.

分散トランザクションへの自動参加Automatically Enlisting in a Distributed Transaction

自動参加は、ADO.NET 接続を System.Transactions に統合する場合の既定の (推奨される) 方法です。Automatic enlistment is the default (and preferred) way of integrating ADO.NET connections with System.Transactions. 接続オブジェクトは、トランザクションがアクティブであると判定されると、既存の分散トランザクションに自動的に参加します。トランザクションがアクティブであることは、System.Transaction から見ると、Transaction.Current が null でないことを意味します。A connection object will automatically enlist in an existing distributed transaction if it determines that a transaction is active, which, in System.Transaction terms, means that Transaction.Current is not null. 自動トランザクション参加は、接続が開かれた場合に行われます。Automatic transaction enlistment occurs when the connection is opened. その後は、コマンドがトランザクションのスコープ内で実行された場合でも、自動トランザクション参加は行われません。It will not happen after that even if a command is executed inside of a transaction scope. Enlist=false の接続文字列パラメーターとして SqlConnection.ConnectionString を指定するか、OLE DB Services=-7 の接続文字パラメーターとして OleDbConnection.ConnectionString を指定すると、既存のトランザクションへの自動参加を無効にできます。You can disable auto-enlistment in existing transactions by specifying Enlist=false as a connection string parameter for a SqlConnection.ConnectionString, or OLE DB Services=-7 as a connection string parameter for an OleDbConnection.ConnectionString. Oracle および ODBC 接続文字列パラメーターの詳細については、「OracleConnection.ConnectionString」および「OdbcConnection.ConnectionString」を参照してください。For more information on Oracle and ODBC connection string parameters, see OracleConnection.ConnectionString and OdbcConnection.ConnectionString.

手動による分散トランザクションへの参加Manually Enlisting in a Distributed Transaction

自動参加が無効になっている場合、または接続が開いた後に開始したトランザクションに参加する必要がある場合は、使用中のプロバイダーの EnlistTransaction オブジェクトの DbConnection メソッドを使用して、既存の分散トランザクションに参加できます。If auto-enlistment is disabled or you need to enlist a transaction that was started after the connection was opened, you can enlist in an existing distributed transaction using the EnlistTransaction method of the DbConnection object for the provider you are working with. 既存の分散トランザクションに参加すると、トランザクションがコミットまたはロールバックされた場合、データ ソースに対してコードで行った変更もコミットまたはロールバックされます。Enlisting in an existing distributed transaction ensures that, if the transaction is committed or rolled back, modifications made by the code at the data source will be committed or rolled back as well.

分散トランザクションへの参加は、特にビジネス オブジェクトをプールする場合に適切です。Enlisting in distributed transactions is particularly applicable when pooling business objects. ビジネス オブジェクトが、開かれている接続と共にプールされている場合は、その接続を開くときだけ、自動トランザクション参加が行われます。If a business object is pooled with an open connection, automatic transaction enlistment only occurs when that connection is opened. プールされているビジネス オブジェクトを使用して複数のトランザクションが実行される場合、そのオブジェクトの開かれている接続は、新しく開始されるトランザクションには自動参加しません。If multiple transactions are performed using the pooled business object, the open connection for that object will not automatically enlist in newly initiated transactions. この場合には、接続の自動トランザクション参加を無効にし、EnlistTransaction を使用して、接続をトランザクションに参加させることができます。In this case, you can disable automatic transaction enlistment for the connection and enlist the connection in transactions using EnlistTransaction.

EnlistTransactionは、既存のトランザクションへTransactionの参照である型の単一の引数を受け取ります。EnlistTransaction takes a single argument of type Transaction that is a reference to the existing transaction. 接続の EnlistTransaction メソッドを呼び出した後、接続を使用してデータ ソースに対して行ったすべての変更は、トランザクションに組み込まれます。After calling the connection's EnlistTransaction method, all modifications made at the data source using the connection are included in the transaction. null 値を渡すことで、現在の分散トランザクションから接続の参加が解除されます。Passing a null value unenlists the connection from its current distributed transaction enlistment. この接続は、EnlistTransaction を呼び出す前に開く必要があることに注意してください。Note that the connection must be opened before calling EnlistTransaction.

注意

一度接続を明示的にトランザクションに参加させると、最初のトランザクションが終了するまでは、参加を解除したり別のトランザクションに参加させたりすることはできません。Once a connection is explicitly enlisted on a transaction, it cannot be un-enlisted or enlisted in another transaction until the first transaction finishes.

注意事項

接続の EnlistTransaction メソッドを使用してトランザクションが既に開始していた場合、BeginTransaction は例外をスローします。EnlistTransaction throws an exception if the connection has already begun a transaction using the connection's BeginTransaction method. ただし、トランザクションがデータ ソースで開始されたローカル トランザクションである場合 (たとえば SqlCommand を使用して BEGIN TRANSACTION ステートメントを明示的に実行した場合)、EnlistTransaction はローカル トランザクションをロールバックし、要求されたように既存の分散トランザクションに参加します。However, if the transaction is a local transaction started at the data source (for example, executing the BEGIN TRANSACTION statement explicitly using a SqlCommand), EnlistTransaction will roll back the local transaction and enlist in the existing distributed transaction as requested. ローカル トランザクションがロールバックされたことは通知されないため、BeginTransaction を使用して開始したのではないローカル トランザクションについては、自分で管理する必要があります。You will not receive notice that the local transaction was rolled back, and must manage any local transactions not started using BeginTransaction. .NET Framework Data Provider for SQL Server (SqlClient) を SQL Server で使用する場合は、参加を試みると例外がスローされます。If you are using the .NET Framework Data Provider for SQL Server (SqlClient) with SQL Server, an attempt to enlist will throw an exception. その他の場合については検出されません。All other cases will go undetected.

SQL Server の昇格可能なトランザクションPromotable Transactions in SQL Server

SQL Server は、軽量のローカル トランザクションを必要に応じて分散トランザクションに自動的に昇格できる、昇格可能なトランザクションをサポートしています。SQL Server supports promotable transactions in which a local lightweight transaction can be automatically promoted to a distributed transaction only if it is required. 昇格可能なトランザクションは、必要な場合以外、分散トランザクションのオーバーヘッドの増加を引き起こすことはありません。A promotable transaction does not invoke the added overhead of a distributed transaction unless the added overhead is required. 詳細とコードサンプルについては、「 SQL Server とのシステムトランザクション統合」を参照してください。For more information and a code sample, see System.Transactions Integration with SQL Server.

分散トランザクションの設定Configuring Distributed Transactions

分散トランザクションを使用するには、ネットワーク上の MS DTC を有効にする必要があります。You may need to enable the MS DTC over the network in order to use distributed transactions. Windows ファイアウォールを有効にしている場合は、MS DTC サービスでネットワークを使用するか MS DTC ポートを開くことができるようにする必要があります。If have the Windows Firewall enabled, you must allow the MS DTC service to use the network or open the MS DTC port.

関連項目See also