.net 是否可以将System.Transactions.TransactionScope与SqlBulkCopy一起使用?

.net 是否可以将System.Transactions.TransactionScope与SqlBulkCopy一起使用?,.net,sql-server,transactionscope,sqlbulkcopy,.net,Sql Server,Transactionscope,Sqlbulkcopy,非常简单的问题:是否可以将System.Transactions.TransactionScope与SqlBulkCopy一起使用?文档中没有提到任何内容(至少在.NET 4.0中是这样),我的测试表明它不会自动登记到TransactionScope 在批量加载中定义事务的唯一方法(据我所知)是指定batchsize 大容量加载的优点是可以获得大容量更新锁(多线程读取和多线程写入)。使用bcp、大容量插入、ssis数据流任务和(tablock)、插入(列)、从openrowset中选择列(大容量

非常简单的问题:是否可以将
System.Transactions.TransactionScope
SqlBulkCopy
一起使用?文档中没有提到任何内容(至少在.NET 4.0中是这样),我的测试表明它不会自动登记到
TransactionScope

在批量加载中定义事务的唯一方法(据我所知)是指定batchsize

大容量加载的优点是可以获得大容量更新锁(多线程读取和多线程写入)。使用bcp、大容量插入、ssis数据流任务和(tablock)、插入(列)、从openrowset中选择列(大容量)或sqlbulkcopy时会出现这种情况。这在尝试最小化加载时间和事务日志大小时非常方便(仅当您满足了最少记录的要求时,这将为您节省数百万行的时间)

无论何时加载数据,事务日志都将成为瓶颈。如果时间至关重要,那么将日志记录的数量降至最低是很重要的


一旦满足batchsize(指定提交的行数),事务就会被提交并重新开始。如果指定batchsize为0,则事务将覆盖整个文件,并在出现任何数据问题时回滚

要执行跨所有批处理(以及可选的跨其他数据库语句)的原子SqlBulkCopy导入,我们需要使用事务。以下步骤概述了将事务与SqlBulkCopy一起使用的过程:

  • 创建到目标数据库服务器的SqlConnection
  • 打开连接
  • 创建SqlTransaction对象
  • 创建传入SqlTransaction对象的SqlBulkCopy对象 进入构造函数
  • 在 试着…抓住挡块。 如果操作完成,提交事务;如果失败,请将其回滚

  • SqlBulkCopy
    从不登记到事务中
    SqlCommand
    也不这样做。常见的误解。登记在
    SqlConnection.Open调用时执行。此后,在该连接上运行的任何内容都隐式地成为事务的一部分。事实上,它不再被允许传递显式事务

    如果希望
    SqlBulkCopy
    使用
    TransactionScope
    参与
    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.
    }
    
    这个代码就是你所需要的。可能的错误:

  • 交易必须足够早地打开
  • 不要使用
    SqlBulkCopy
    SqlTransaction
    参数。传递
    null
  • 不要使用
    SqlBulkCopyOptions。请使用InternalTransaction
  • 除非您想实际执行某些操作,否则不要添加异常处理。如果没有提交,则自动回滚
  • 使用
    using
    语句清除代码和确定性清除。除非必须,否则不要手动关闭或处置这些对象。这是多余的

  • 您可以使用您喜欢的任何批次大小,所有批次都将成为事务的一部分。因此,批处理的价值有限(尤其是事务日志不能提前截断)。首先不要尝试配料。

    这很不幸。我将单行提交和大容量加载到多个表中,然后在另一个表中进行单行更新,要么全部成功,要么全部失败。我希望在一个
    TransactionScope
    中轻松完成提交、批量加载和最终更新。我只需要采取另一种方法。感谢您的详细回答,非常感谢。我们有两个数据库涉及到什么?此回答不解释所问的TransactionScope。以下是一些关于TransactionScope的回答,对您的情况有帮助