2016-08-29 4 views
5

Я в основном из базы данных и нового в .net. Пожалуйста, несите меня, если мой вопрос звучит глупо.Retryable SQLBulkCopy для SQL Server 2008 R2

Я использую SqlBulkCopy в своем коде для передачи данных с одного SQL Server на другой. Но он часто не работает из-за сетевых проблем. Чтобы избежать этого, я планирую сделать две вещи

  1. Уменьшить размер партии (от 5000 до 1000) и увеличить время ожидания (от 3мин. До 1мин)

  2. Внедрение повторов логика

Мой вопрос:

  1. Каков наилучший способ реализации повторной попытки, то есть на уровне таблицы или на уровне партии (если вообще возможное)?
  2. Я нашел некоторую работу фрейма для отказоустойчивости SQL Azure здесь: https://msdn.microsoft.com/en-us/library/hh680934(v=pandp.50).aspx Есть ли у нас что-то подобное для SQL Server 2008 R2?

Пример кода, который я использую:

private void BulkCopyTable(string schemaName, string tableName) 
    {using (var reader = srcConnection.ExecuteReader($"select * from [{SourceDBName}].[{schemaName}].[{tableName}]")) 
      { 
       const SqlBulkCopyOptions bulkCopyOptions = SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.FireTriggers | 
                  SqlBulkCopyOptions.KeepNulls | 
                  SqlBulkCopyOptions.KeepIdentity; 

       using (var bcp = new SqlBulkCopy(dstConnection.ConnectionString, bulkCopyOptions)) 
       { 
        const int threeMinutes = 60*3; 
        bcp.BulkCopyTimeout = threeMinutes; //Timeout is for a single batch 
        bcp.BatchSize = 5000; 
        bcp.DestinationTableName = $"[{DestinationDB}].[{schemaName}].[{tableName}]"; 
        bcp.EnableStreaming = true; 
        foreach (var col in table.Columns.Cast<Column>().Where(c => !c.Computed)) 
        { 
         bcp.ColumnMappings.Add(col.Name, col.Name); 
        } 
        bcp.WriteToServer(reader); 
       } 
      } 
     } 
+0

Показать код C#, где вы делаете SqlBulkCopy. –

+0

@SarveshMishra, обновил описание с помощью кода. – SumanKumar

ответ

0

Простой подход заключается в следующем:

  1. Реализовать Порции себя. Это приводит к незначительной неэффективности, так как SqlBulkCopy нуждается в запросе метаданных для каждого вызова WriteToServer. Поэтому не делайте партии слишком маленькими. Эксперимент.
  2. Вставьте во временную таблицу (не таблицу #temp, но прочную, чтобы вы могли потерять соединение и продолжить).
  3. Затем выполните insert...select в качестве последнего шага для перемещения строк из таблицы temp в реальную таблицу.

Этот танец разбивает работу на повторные партии, но действует так, как если бы это была одна транзакция.

Если вам не нужна атомичность, вы можете оставить его на шаге (1).

Смежные вопросы