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

Jür*_*yer 10 .net windows sql-server sqlbulkcopy

我试图找到使用SqlBulkCopy与SqlBulkCopyOptions.UseInternalTransaction复制选项和没有它之间的区别,但在我的测试应用程序中,我没有发现任何差异.如果BatchSize是例如0并且我添加了100条记录(在a中DataTable),其中记录号50在将其添加到数据库表时导致错误,我在表中得到0条记录.BatchSize例如,如果设置为10,则会获得40条记录(4批10条记录,第5批包含错误记录并导致批量复制中止).如果qlBulkCopyOptions.UseInternalTransaction设置了S无关紧要,我总能得到相同的结果.看起来批次总是复制在内部事务中.

如果您对我的测试应用程序感兴趣,那么它是: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似乎是多余的,但为了安全起见,我会设置它.

Mar*_*ith 6

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

_internalTransaction = _connection.BeginTransaction();
Run Code Online (Sandbox Code Playgroud)

每批次周围。

但此选项与 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();
Run Code Online (Sandbox Code Playgroud)

通过失败并出现SqlBulkCopyOptions.UseInternalTransaction错误

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

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