简体   繁体   English

SqlBulkCopy会自动启动事务吗?

[英]Does SqlBulkCopy automatically start a transaction?

I am inserting data via SqlBulkCopy like so: 我通过SqlBulkCopy插入数据,如下所示:

public void testBulkInsert(string connection, string table, DataTable dt)
{
    using (SqlConnection con = new SqlConnection(connection))
    {
        con.Open();

        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(con))
        {
            bulkCopy.DestinationTableName = table;
            bulkCopy.WriteToServer(dt);
        }
    }
}

Will this automatically be wrapped in a SQL transaction so that if something goes wrong half way through the DB will be left in the same state as it was before the bulk insert began? 这会自动包装在SQL事务中,这样如果出现问题,数据库的一半将保持与批量插入开始之前相同的状态吗? Or will half the data be inserted? 或者将插入一半的数据?

ie is it necessary for me to explicitly call con.BeginTransaction 即我是否有必要明确调用con.BeginTransaction

Or if I call SqlBulkCopy 's constructor that takes a string, is that a better way of getting it to occur in a transaction? 或者如果我调用SqlBulkCopy的构造函数来获取字符串,那么这是一种更好的方法来使它在事务中发生吗?

public void testBulkInsert(string connection, string table, DataTable dt)
{
    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
    {
        bulkCopy.DestinationTableName = table;
        bulkCopy.WriteToServer(dt);
    }
}

I find the docs a bit unclear on this matter as they initially state that 我发现这个问题的文档有点不清楚,因为他们最初表明了这一点

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 批量复制操作以非事务方式发生,没有机会将其回滚

but then later state 但后来说明了

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. 如果要执行专用批量复制操作,请使用连接字符串创建SqlBulkCopy的新实例,或使用不带活动事务的现有SqlConnection对象。 In each scenario, the bulk copy operation creates, and then commits or rolls back the transaction. 在每个方案中,批量复制操作都会创建,然后提交或回滚事务。

So is it necessary to do: 所以有必要这样做:

public void testBulkInsert(string connection, string table, DataTable dt)
{
    using (SqlConnection con = new SqlConnection(connection))
    {
        con.Open();
        using (SqlTransaction tr = con.BeginTransaction(IsolationLevel.Serializable))
        {
            using (SqlBulkCopy bulkCopy = new SqlBulkCopy(con, SqlBulkCopyOptions.Default, tr))
            {
                bulkCopy.DestinationTableName = table;
                bulkCopy.WriteToServer(dt);
            }
            tr.Commit();
        }
    }
}

No here is text from SqlBulkCopy documentation in msdn 这里没有来自msdn中 SqlBulkCopy文档的文本

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. 如果在发生错误时需要回滚全部或部分批量复制,则可以使用SqlBulkCopy管理的事务 ,在现有事务中执行批量复制操作,或者在System.Transactions事务中登记。

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 如果要执行专用批量复制操作,请使用连接字符串创建SqlBulkCopy的新实例,或使用
existing SqlConnection object without an active transaction. 没有活动事务的现有SqlConnection对象。 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 ! 仔细查看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. 您在SqlBulkCopy类构造函数中显式指定UseInternalTransaction选项,以显式地使批量复制操作在其自己的事务中执行,从而导致每批批量复制操作在单独的事务中执行。因为不同的批处理在不同的事务中执行,如果在批量复制操作期间发生错误,则将回滚当前批次中的所有行,但以前批次中的行将保留在数据库中。


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. 如果由于发生错误而需要回滚整个批量复制操作,或者如果批量复制应作为可以回滚的较大进程的一部分执行,则可以向SqlBulkCopy构造函数提供SqlTransaction对象。

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. 如果你想要交易,你应该使用我写的两个案例之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM