12

我试图找出使用带有SqlBulkCopyOptions.UseInternalTransaction复制选项的 SqlBulkCopy 与不使用它之间的区别,但在我的测试应用程序中,我没有发现任何区别。例如,如果BatchSize是 0 并且我添加了 100 条记录(在 a 中DataTable),其中记录号 50 在将其添加到数据库表时会导致错误,我在表中得到 0 条记录。例如,如果BatchSize设置为 10,我得到 40 条记录(4 批 10 条记录,第五批包括错误记录并导致批量复制中止)。不管 SqlBulkCopyOptions.UseInternalTransaction是否设置,我总是得到相同的结果。似乎批次总是在内部事务中复制。

如果你对我的测试应用程序感兴趣,这里是:SqlBulkCopy-Error-and-Transaction-Test.zip

我的问题是:

  1. 是否因为总是使用内部事务SqlBulkCopyOptions.UseInternalTransaction而过时?SqlBulkCopy
  2. 如果不是:此选项的实际含义是什么?在哪些情况下会有所作为?

希望有人能澄清

编辑: 根据答案和评论,我认为我的问题还不够清楚。我知道文档。它说“默认情况下,批量复制操作是它自己的事务。” 并且每个批次在传递时都使用它自己的事务UseInternalTransaction. 但是,如果这意味着默认情况下,大容量复制操作对整个大容量复制仅使用一个事务(而不是每个批次一个事务),如果我将 BatchSize 设置为某个大小并且批次位于之后,我将不会在数据库中获取记录第一个导致错误。如果只使用一个事务,则添加到事务日志的所有记录都将回滚。但是我得到了包含错误记录的批次之前的批次记录。据此,似乎默认情况下每个批次都在其自己的事务中执行。这意味着我通过UseInternalTransaction与否无关紧要。如果我在这里走错了路,如果有人能澄清一下,我将不胜感激。

一个事实可能很重要:我使用的是 SQL Server 2012。也许 SQL Server 2008 的行为有所不同。我会检查的。

编辑:感谢 usr 的回复,我想我找到了答案:我进行了一些调试和分析,发现如果未定义 UseInternalTransaction,则确实未设置私有字段 _internalTransaction。SqlBulkCopy 然后不使用自己的(内部)事务。但是分析表明 SqlBulkCopy 使用 TDS(表格数据流)来复制数据(无论 BatchSize 是什么)。我没有找到太多关于 TDS 的信息,尤其是对于 SQL Server,但我假设 SQL Server 在内部事务中执行 TDS 大容量复制操作。因此 UseInternalTransaction 对于 SQL Server 来说似乎有点多余,但为了安全起见,我会设置它。

4

1 回答 1

4

如果设置此选项,则 SQLBulkCopy 类将添加一个

_internalTransaction = _connection.BeginTransaction();

围绕每批。

但是此选项与 SQL Server 没有实际区别,因为默认情况下事务无论如何都在自动提交模式下运行。

唯一可观察到的区别是它执行您还没有尝试传递外部事务的验证。

以下将成功并回滚所有批次

var transaction = sourceConnection.BeginTransaction();             
using (SqlBulkCopy bulkCopy =
    new SqlBulkCopy(sourceConnection, SqlBulkCopyOptions.Default, transaction))

{
    bulkCopy.BatchSize = 50;

    bulkCopy.DestinationTableName = "dbo.foobar";
        bulkCopy.WriteToServer(dt);
}

transaction.Rollback();

传递SqlBulkCopyOptions.UseInternalTransaction失败并出现错误

不得同时指定 SqlBulkCopyOption.UseInternalTransaction 并传递外部 Transaction。

我想知道如果SET IMPLICIT_TRANSACTIONS ON;以前在连接上运行过以关闭自动提交模式但SqlBulkCopy采用连接对象的构造函数的重载返回“意外的现有事务”是否会有所不同。无论如何,在这两种情况下都会出错 - 采用连接字符串的重载只会创建一个新连接。

于 2015-04-05T19:46:59.357 回答