Does SqlBulkCopy automatically start a transaction?

后端 未结 1 1863
小鲜肉
小鲜肉 2020-12-24 02:51

I am inserting data via SqlBulkCopy like so:

public void testBulkInsert(string connection, string table, DataTable dt)
{
    using (SqlConnectio         


        
相关标签:
1条回答
  • 2020-12-24 03:39

    No here is text from SqlBulkCopy documentation in msdn

    By default, a bulk copy operation is performed as an isolated operation. The bulk copy operation occurs in a non-transacted way, with no opportunity for rolling it back. If you need to roll back all or part of the bulk copy when an error occurs, you can use a SqlBulkCopy-managed transaction, perform the bulk copy operation within an existing transaction, or be enlisted in a System.Transactions Transaction.

    EDIT: Read properly the documentation, from the link which I gave you:

    By default, a bulk copy operation is its own transaction. When you want to perform a dedicated bulk copy operation, create a new instance of SqlBulkCopy with a connection string, or use an
    existing SqlConnection object without an active transaction. In each scenario, the bulk copy operation creates, and then commits or rolls back the transaction.

    This is written for the case internal bulk copy transaction, which is not the default!

       using (SqlBulkCopy bulkCopy = new SqlBulkCopy(
                           connectionString, SqlBulkCopyOptions.KeepIdentity |
                           SqlBulkCopyOptions.UseInternalTransaction))
       {
           ....
       }
    

    Look closely in SqlBulkCopyOptions.UseInternalTransaction ! You are explicitly specify the UseInternalTransaction option in the SqlBulkCopy class constructor to explicitly cause a bulk copy operation to execute in its own transaction, causing each batch of the bulk copy operation to execute within a separate transaction.Since different batches are executed in different transactions, if an error occurs during the bulk copy operation, all the rows in the current batch will be rolled back, but rows from previous batches will remain in the database.


    If you need to roll back the entire bulk copy operation because an error occurs, or if the bulk copy should execute as part of a larger process that can be rolled back, you can provide a SqlTransaction object to the SqlBulkCopy constructor.

    The external transaction case.

                using (SqlTransaction transaction =
                           destinationConnection.BeginTransaction())
                {
                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(
                               destinationConnection, SqlBulkCopyOptions.KeepIdentity,
                               transaction))
                    {
                         ....
                    }
                }
    

    Like I said in the begging the answer is no, you should use existing transaction or internal bulk copy transaction. Read the documentation file which is in the link, for more information.

    If you want to have transaction you should use one of the two cases which I wrote.

    0 讨论(0)
提交回复
热议问题