SqlBulkCopy:В чем разница между передачей SqlBulkCopyOptions.UseInternalTransaction и отказом от ее передачи?

Я пытаюсь найти разницу между использованием SqlBulkCopy с опцией копирования SqlBulkCopyOptions.UseInternalTransactionи без нее, но в своем тестовом приложении я не обнаруживаю никакой разницы. Если BatchSize, например, равно 0, и я добавляю 100 записей (в DataTable), где запись номер 50 вызывает ошибку при добавлении ее в таблицу базы данных, я получаю 0 записей в таблице. Например, если для BatchSizeустановлено значение 10, я получаю 40 записей (4 пакета по 10 записей, пятый пакет включает ошибочную запись и приводит к прекращению массового копирования). Неважно, установлен S qlBulkCopyOptions.UseInternalTransactionили нет, я всегда получаю один и тот же результат. Похоже, что пакеты всегда копируются во внутренней транзакции.

Если вас заинтересовало мое тестовое приложение, вот оно:SqlBulkCopy-Error-and-Transaction-Test.zip

Мои вопросы:

  1. Is SqlBulkCopyOptions.UseInternalTransactionустарело, потому что SqlBulkCopyвсегда использует внутренние транзакции?
  2. Если нет:В чем смысл этой опции? В каких случаях это будет иметь значение?

Надеюсь, кто-то сможет прояснить

Изменить: Судя по ответу и комментариям, я предполагаю, что моя проблема недостаточно ясна. Я знаю документацию. В нем говорится, что «По умолчанию операция массового копирования является отдельной транзакцией». и что каждый пакет использует свою собственную транзакцию при передаче UseInternalTransaction. Но если это означает, что по умолчанию операция массового копирования использует только одну транзакцию для всего массового копирования (, а не по одной для каждого пакета), я не получу записи в базе данных, если установлю BatchSize на определенный размер и партия, лежащая после первой, вызывает ошибку. Если бы использовалась только одна транзакция, все записи, добавленные в журнал транзакций, были бы отброшены.Но я получаю записи партий, которые лежат перед партией, включающей ошибочную запись. В соответствии с этим кажется, что по умолчанию каждый пакет выполняется в своей собственной транзакции. Это означает, что не имеет значения, сдам ли я UseInternalTransactionили нет. Если я на неправильном пути, я был бы очень признателен, если бы кто-нибудь мог уточнить.

Один факт может оказаться важным:Я использую SQL Server 2012. Возможно, SQL Server 2008 ведет себя по-другому. Я проверю это.

Редактировать:Благодаря ответу от usr я думаю, что нашел ответ:Я немного отладил и профилировал и обнаружил, что приватное поле _internalTransaction действительно не установлено, если UseInternalTransaction не определено. Тогда SqlBulkCopy не использует собственную (внутреннюю)транзакцию. Но профилирование показало, что SqlBulkCopy использует TDS (Tabular Data Stream)для копирования данных (независимо от размера BatchSize). Я не нашел много информации о TDS, особенно для SQL Server, но я предполагаю, что SQL Server выполняет операции массового копирования TDS во внутренней транзакции. Поэтому UseInternalTransaction кажется избыточным для SQL Server, но на всякий случай я бы установил его.

10
задан Jürgen Bayer 16 April 2012 в 10:06
поделиться