質問: 非常に簡単な質問: `System.Transactions.TransactionScope`と`SqlBulkCopy`を併用することは可能ですか? トランザクションとバルクコピー操作のドキュメントには何も言及されていません(少なくとも.NET 4.0以降)、私のテストでは`TransactionScope`自動的に参加しないことが示されています。
回答: `SqlBulkCopy`は決してトランザクションに`SqlBulkCopy`ません。 `SqlCommand`もそれをしません。よくある誤解。参加は、 `SqlConnection.Open`が呼び出された時点で実行されます。その後、その接続で実行されるものは暗黙的にトランザクションの一部になります。実際、もはや明示的なトランザクションを渡すことが*許可さ*れ*ません* 。 `TransactionScope`を使用して`SqlBulkCopy`を`System.Transactions.Transaction`参加させるには、接続を開くときにトランザクションを設定する必要があります。 それは非常に簡単です: ``` using (var tran = new TransactionScope(...)) using (var conn = new SqlConnection(connStr)) { conn.Open(); //This enlists. using (var sqlBulkCopy = new SqlBulkCopy(conn)) { sqlBulkCopy.WriteToServer(...); } tran.Complete(); //Commit. } ``` このコードはあなたが必要とするものです。考えられる間違い: 1. トランザクションは早めに開かなければなりません。 2. `SqlBulkCopy`の`SqlTransaction`パラメーターは使用しないで`SqlBulkCopy` 。 `null`渡し`null` 。 3. `SqlBulkCopyOptions.UseInternalTransaction`は使用しないでください。 4. 実際に何かしたいのでなければ例外処理を追加しないでください。コミットがない場合、ロールバックは自動です。 5. クリーンコードと確定的クリーンアップには`using`ステートメントを使用します。必要がない限り、これらのオブジェクトを手動で閉じたり破棄したりしないでください。これは冗長です。 あなたは好きなバッチサイズを使うことができ、すべてのバッチはトランザクションの一部になります。したがって、バッチ処理には制限があります(特に、トランザクションログを早期に切り捨てることはできません)。最初はバッチ処理をしないでください。