2010-05-12 4 views
1

У меня есть пользовательский исполняемый файл импорта данных в .NET 3.5, который SqlBulkCopy в основном делает более быстрые вставки на большие объемы данных. Приложение в основном принимает входной файл, массирует данные и загружает их в SQL Server 2000. Он был написан консультантом, который строит его с базой данных SQL 2008. Может ли это быть причиной этого? У SQL 2000 есть утилита bcp, на которой базируется BulkCopy. Итак, когда мы это запустили, это вызвало ошибку Deadlock.SqlBulkCopy вызывает deadlock на SQL Server 2000

Сведения об ошибке: Транзакция (идентификатор процесса 58) была заблокирована при блокировке ресурсов другим процессом и была выбрана в качестве жертвы взаимоблокировки. Перезапустите транзакцию.

Я пробовал множество способов решить проблему. например, временную установку переменной строки соединения MultipleActiveResultSets = true, которая не была идеальной, но она по-прежнему дает ошибку Deadlock. Я также убедился, что это не проблема с тайм-аутом соединения.

здесь функция. Любой совет?

/// <summary> 
    /// Bulks the insert. 
    /// </summary> 
    public void BulkInsert(string destinationTableName, DataTable dataTable) 
    { 
     SqlBulkCopy bulkCopy; 

     if (this.Transaction != null) 
     { 
      bulkCopy = new SqlBulkCopy 
       (
        this.Connection, 
        SqlBulkCopyOptions.TableLock, 
        this.Transaction 
       ); 
     } 
     else 
     { 
      bulkCopy = new SqlBulkCopy 
       (
        this.Connection.ConnectionString, 
        SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.UseInternalTransaction 
       ); 
     } 

     bulkCopy.ColumnMappings.Add("FeeScheduleID", "FeeScheduleID"); 
     bulkCopy.ColumnMappings.Add("ProcedureID", "ProcedureID"); 
     bulkCopy.ColumnMappings.Add("AltCode", "AltCode"); 
     bulkCopy.ColumnMappings.Add("AltDescription", "AltDescription"); 
     bulkCopy.ColumnMappings.Add("Fee", "Fee"); 
     bulkCopy.ColumnMappings.Add("Discount", "Discount"); 
     bulkCopy.ColumnMappings.Add("Comment", "Comment"); 
     bulkCopy.ColumnMappings.Add("Description", "Description"); 


     bulkCopy.BatchSize = dataTable.Rows.Count; 
     bulkCopy.DestinationTableName = destinationTableName; 
     bulkCopy.WriteToServer(dataTable); 

     bulkCopy = null; 
    } 
+1

Как насчет информации о тупике? См. Http://msdn.microsoft.com/en-us/library/ms190465.aspx о том, как его захватить. –

ответ

0

Я использую BCP довольно регулярно, и я никогда не видел случай, когда BATCHSIZE был установлен на что-нибудь другое, чем типичное значение 1000.

Это поле не должно представлять цельные подсчет строк, как показано в коде, но для представления управляемых блоков данных, которые должны быть отправлены на сервер во время копирования, вроде как размер IP-пакета.

Вы можете попробовать изменить это значение на 1000 вместо всей таблицы.

Возможно, вы также захотите просмотреть панели управления процессом/блокировкой в ​​SQL Enterprise Manager или SQL Management Studio (в зависимости от версии вашего клиентского инструмента) и посмотреть, что этот процесс выполняет с точки зрения блокировок.

+0

, что BatchSize фактически задается параметром в app.config. Мы массируем данные плоского файла в временную таблицу, потому что нам нужны соответствующие значения из других таблиц для каждого rec, размер определяется конфигурацией var.Я тестировал размер партии в разных размерах от 50 до 50000 или около того. – stevenjmyu

+0

Но ваш сегмент кода выше показывает, что он явно установлен в коде для результата DataTable.Rows.Count, поэтому, где это значение в файле конфигурации входит в игру, поскольку я не вижу его в вашем коде. – Bill

0

Эти вставки выполняются одновременно? Известная проблема с SqlBulkCopy при выполнении параллельных вставок с подсказкой TABLOCK в таблице с кластеризованными индексами. Это вызывает тупик. Смотрите следующее:

http://msdn.microsoft.com/en-us/library/ms186341(SQL.90).aspx

+0

Нет, это не параллельный импорт. Парень, который написал его, смог запустить его локально с созданной базой данных, за исключением того, что он был в 2008 году и не имеет большого количества данных, мы попытались установить SqlBulkCopyOptions.Defaults, который вместо этого блокирует строку, но все же видит тупик , – stevenjmyu

0

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

SQL Server 2000 не имеет такой сложной эскалации блокировки, как более поздние версии. Я ожидаю, что это то, что вы видите. Я предполагаю, что у консультанта нет рабочей нагрузки, отличной от BCP, в таблице назначения, в то время как ваше приложение действительно имеет активность в таблице адресатов, отличной от основной вставки.

Я бы подумал о том, чтобы сделать свою основную вставку в промежуточную таблицу (так что нет шансов на блокировку там), а затем как можно более эффективный запрос на вставку/обновление (возможно, во многих небольших партиях) в собственном SQL SP.

0

Я, наконец, смог получить локальную копию нашей производственной базы данных (~ 50 концертов), чтобы протестировать приложение. Оказывается, дело в том, что сделка была исключительно проблемой окружающей среды. Спасибо, ребята.

+0

Поздравляем! Рад слышать, что вы смогли заставить его работать. – Garett

+1

Итак, какова была проблема с окружающей средой? Как вы это решили? – skimania

+0

@stevenjmyu Не могли бы вы рассказать о шагах, которые вы предприняли для решения этой проблемы? –

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