SqlBulkCopy.WriteToServer зависает Thread.Abort вызывается, но не уверен, почему

Дано:

  • Класс BenchMark, который дает мне знать, когда что-то завершено.
  • Очень большой файл XML (~ 120 МБ), который был разобран на несколько списков.

Некоторый код:

SqlConnection con = null;
SqlTransaction transaction = null;

try
{
  con = getCon(); // gets a new connection object
  con.Open();
  transaction = con.BeginTransaction();

  var bulkCopy = new SqlBulkCopy(con, SqlBulkCopyOptions.Default, transaction)
  {
    BatchSize = 1000,
    DestinationTableName = "Table1"
  };

  // assume that the BenchMark class is working
  b = new BenchMark("Table1");
  bulkCopy.WriteToServer(_insertTable1s.AsDataReader()); // _insertTables1s is a List<Table1>
  b.Complete();
  LogHelper.WriteLogItem(b);

  b = new BenchMark("Table2");
  bulkCopy.DestinationTableName = "Table2";
  bulkCopy.WriteToServer(_insertTable2s.AsDataReader()); // _insertTables2s is a List<Table2>
  b.Complete();
  LogHelper.WriteLogItem(b);

  // etc... this code does a batch insert into about 7 tables all having about 40,000 records being inserted.

  b = new BenchMark("Transaction Commit");
  transaction.Commit();
  b.Complete();
}
catch (Exception e)
{
  transaction.Rollback();

  LogHelper.WriteLogItem(
    LogLevel.Critical,
    LogType.DataProcessing,
    e.ToString());
}
finally
{
  con.Close();
}

Проблема:

В моей локальной среде разработки все в порядке. Когда я запускаю эту операцию в облаке, она зависает. Используя метод LogHelper.WriteLogItem, я могу наблюдать за ходом этого процесса. Я наблюдаю, как он зависает случайным образом на определенном столе. Исключение не выдается, поэтому транзакция не откатывается. Скажем, зависает на Table2 массовой вставке. Используя MS SQL Management Studio, я запускаю запросы на Table3, Table2 и Table1 без проблем (это означает, что транзакция была прервана?)

Так как зависает, пойду перезапускать процесс. На этот раз он зависает раньше, поэтому я могу получить такие журналы:

7755   Benchmark   LoadXML took 00:00:04.2432816
7756   Benchmark   Table1 took 00:00:06.3961230
7757   Benchmark   Table2 took 00:00:05.2566890
7758   Benchmark   Table3 took 00:00:08.4900921
7759   Benchmark   Table4 took 00:00:02.0000123

... он зависает на Table5 (потому что BenchMark так и не завершился). Я запускаю его снова, и остальная часть журнала выглядит так:

7780   Benchmark   LoadXML took 00:00:04.1203923

...и теперь висит здесь.

Я использую облачный хостинг в стойке, если это поможет. Раньше мне удавалось исправить это, удалив все таблицы из файла dbml и прочитав их, но на этот раз это не работает. Мне интересно, вызывает ли проблема объем обрабатываемых данных?

EDIT: код в этом примере выполняется в асинхронном потоке. Я обнаружил, что поток прерывается по неизвестной причине, и мне нужно выяснить причину, чтобы решить эту проблему.


person aarona    schedule 26.04.2011    source источник
comment
Можете ли вы попробовать выполнить коммит транзакции после каждого массового копирования и посмотреть, что произойдет потом?   -  person mservidio    schedule 27.04.2011
comment
Я посмотрю, сработает ли это, но это не решит проблему, потому что данные имеют версии, а транзакция должна быть атомарной.   -  person aarona    schedule 27.04.2011
comment
С каким типом количества строк на массовую вставку вы имеете дело?   -  person mservidio    schedule 27.04.2011
comment
примерно 40000 для большинства столов и от 500 до 1500 для одного или двух из них.   -  person aarona    schedule 27.04.2011
comment
Я решил проблему, удалив таблицы на сервере и используя SQL Compare для повторной синхронизации схемы таблицы. Не лучшее решение, поэтому я жду, когда кто-нибудь придумает лучшую идею.   -  person aarona    schedule 27.04.2011


Ответы (2)


Если у вас есть администратор на вашем сервере или базе данных, вы можете запустить

SELECT * FROM sys.dm_tran_session_transactions

чтобы узнать, какие транзакции активны в данный момент — из Пинал

Кроме того, для убедитесь, что ничто не блокирует вашу транзакцию.

person davisoa    schedule 26.04.2011
comment
+1, потому что это полезно, но мне это не поможет, потому что мои среды разработки и производства размещены в облаке, поэтому у меня нет доступа к этой таблице/представлению. - person aarona; 27.04.2011

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

Я предполагаю, что реальная проблема заключается в том, почему мой поток прерывается, поскольку я не прерываю его ни в одном из своих кодов. Я считаю, что это связано с объемом обрабатываемых данных, но я могу ошибаться.

В любом случае, я решил свою проблему.

person aarona    schedule 29.04.2011