SqlBulkCopy иногда не работает, и при восстановлении индекса таблицы не возвращаются ошибки - PullRequest
0 голосов
/ 10 мая 2019

SqlBulkCopy.WriteToServer (DataTable) иногда не работает во время процесса перестроения индекса моей таблицы

Это можно легко смоделировать с помощью следующего способа:

  1. Создать таблицу с10 столбцов с кластеризованным индексом (первичный ключ) и 2 некластеризованных индекса
  2. Заполнение таблицы 500 000 фиктивных данных
  3. Создание программы для вставки 100 записей в таблицу (запустить еев цикле 50 раз)
  4. Во время работы программы продолжайте выполнять команду перестроения индекса, пока программа не остановится:

    ALTER INDEX [IX_11] ON [dbo] .TableA1 REBUILDWITH (SORT_IN_TEMPDB = OFF, ONLINE = ON)
    ALTER INDEX [IX_12] ON [dbo] .TableA1 REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE = ON)

  5. Вы будетев состоянии видеть, что иногда нет ошибок (и число скопированных строк, возвращаемых SQLBulkCopy, составляет 50000), но в базе данных только 49000

Код:

    SqlConnection conn = new SqlConnection(strConnection);
    conn.Open();
    using (SqlTransaction transaction = conn.BeginTransaction())
    {
        try
        {
            using (SqlBulkCopy bulkCopyItem = new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, transaction))
            {
                try
                {
                    bulkCopyItem.BulkCopyTimeout = 300;
                    foreach (DataColumn col in DataTableABC.Columns)
                    {
                        bulkCopyItem.ColumnMappings.Add(col.ColumnName, col.ColumnName);
                    }
                    bulkCopyItem.BatchSize = 100;
                    bulkCopyItem.DestinationTableName = "dbo.TableA1";
                    bulkCopyItem.WriteToServer(DataTableABC); // prove await also can cause problem



                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    _logger.Error("Message=" + ex.Message + " ;" + TaskNo);
                    transaction.Rollback();
                }
            }
        }
        catch (Exception ex)
        {
            _logger.Error("Message=" + ex.Message + " ;" + TaskNo);
        }
    }
    conn.Close();

Примечание:

  1. Сбой довольно часто с "исключением изменения схемы ...".Это нормально, мы можем повторить попытку при появлении ошибки.Проблема в том, что SQLBulkCopy не возвращает никаких ошибок, а данные не вставляются в БД
  2. Работает нормально, используя SqlBulkCopyOptions.UseInternalTransaction
  3. Работает нормально, если BatchSize <> 0 (так долго, как размер пакета)меньше, чем фактическое количество строк, он работает нормально)

Поскольку я хочу использовать существующую транзакцию и выполнять пакетную обработку (100 за раз, и BatchSize = 100), я не могу найти какие-либолучший способ решить это.Это происходит только во время запуска задания перестроения индекса

Есть идеи, как избежать этой проблемы?Спасибо

...