SqlBulkCopy:传递SqlBulkCopyOptions.UseInternalTransaction和不传递它有什么区别?

.net sqlbulkcopy sql-server windows

我试图找到使用SqlBulkCopy与SqlBulkCopyOptions.UseInternalTransaction复制选项之间的区别,没有它,但在我的测试应用程序中,我没有发现任何差异。如果BatchSize是例如0并且我添加了100条记录(在DataTable ),其中记录号50在将其添加到数据库表时导致错误,我在表中得到0条记录。例如,如果将BatchSize设置为10,则会获得40条记录(4批10条记录,第5批包含错误记录并导致批量复制中止)。如果设置了S qlBulkCopyOptions.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批量复制操作。因此,对于SQL Server来说,UseInternalTransaction似乎是多余的,但为了安全起见,我会设置它。

热门答案

如果设置此选项,那么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并同时传递外部事务。

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




许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因