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

jas*_*son 32 .net sql-server transactionscope sqlbulkcopy

很简单的问题:是否可以System.Transactions.TransactionScopeSqlBulkCopy?一起使用?文档事务和批量复制操作没有提到任何内容(至少从.NET 4.0开始),我的测试表明它不会自动登记TransactionScope.

usr*_*usr 39

SqlBulkCopy永远不会参与交易.SqlCommand也不这样做.常见的误解.征募是在SqlConnection.Open被召唤时进行的.之后,在该连接上运行的任何内容都是隐式的事务的一部分.实际上,不再允许传递显式事务.

如果要SqlBulkCopy参与System.Transactions.Transaction使用,TransactionScope则必须在打开连接时设置事务.

这很容易做到:

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.
}
Run Code Online (Sandbox Code Playgroud)

这段代码就是您所需要的.可能的错误:

  1. 交易必须尽早开启.
  2. 不要使用SqlTransaction参数SqlBulkCopy.通过null.
  3. 不要用SqlBulkCopyOptions.UseInternalTransaction.
  4. 除非您想要实际执行某些操作,否则不要添加异常处理.如果没有提交,则回滚是自动的.
  5. 使用该using语句进行清除代码和确定性清理.除非必须,否则请勿手动关闭或处置任何这些对象.这将是多余的.

您可以使用任何您喜欢的批量大小,所有批次都将成为交易的一部分.因此,批处理具有有限的价值(特别是事务日志不能提前截断).首先尝试不批处理.


bri*_*ian 3

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

批量加载的优点是可以获得批量更新锁(多线程读取和多线程写入)。当使用 bcp、批量插入、带有 (tablock) 的 ssis 数据流任务、insert(columns)select columns from openrowset (bulk) 或 sqlbulkcopy 时,您会得到此信息。当尝试最小化加载时间和事务日志大小时,这非常方便(仅当您满足最小日志记录要求时,这将为您节省数百万行的时间)。

每当加载数据时,事务日志都将成为瓶颈。如果时间至关重要,那么尽量减少记录的数量就很重要。

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