Время ожидания TransactionScope преждевременно?

Я использую TransactionScope для пакетной вставки и обновлений. Проблема в том, что я получаю исключения тайм-аута для 30-минутной операции, даже когда я установил тайм-аут TransactionScope на один час.

Также после исключения он вставляет, казалось бы, случайное количество записей пакета. Например, последняя операция имела 12440 вставок, а после тайм-аута в таблицу было вставлено 7673 записи.

Таймаут SqlConnection и SqlCommand оба установлены на int.MaxValue.

Что я делаю неправильно?

Вот мой код:

using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromHours(1)))
 {
         try
         {
                using (db = new DB())
                {
                //operations here
                }
         }
         catch (Exception ex)
         {
               throw new Exception("DB Error:\r\n\r\n" + ex.Message);
         }

         transaction.Complete();
} // <--- Exception here: Transaction aborted (Inner exception: Timeout)

person dstr    schedule 28.05.2011    source источник
comment
более серьезный (и, возможно, более важный) вопрос: почему несколько десяти тысяч ВСТАВОК занимают так много времени?   -  person Mitch Wheat    schedule 28.05.2011
comment
Может быть, имеет место тайм-аут команды (и, таким образом, отвлекающий маневр для тайм-аута TransactionScope)? Это объяснило бы случайность, учитывая, что записи вставляются так очень медленно ... Я вижу, что в вопросе указано значение MaxValue, но у меня есть подозрение ... что проблема не в том, чем кажется.   -  person    schedule 28.05.2011
comment
@Mitch: Это делается по одному на очень медленном соединении. Следовательно, тайм-аут в один час :) @pst: Insert выполняется в цикле. Каждая итерация устанавливает CommandText и выполняется. Так что это не ожидание результата большого SQL, я сомневаюсь, что это тайм-аут команды. Также я использую очень простой DAL только с SqlConnection и SqlCommand, я не вижу другого тайм-аута. Я с удовольствием проверил бы что-нибудь еще, что вы могли бы предложить?   -  person dstr    schedule 28.05.2011


Ответы (2)


Сбой вашей транзакции через 10 минут? Если это так, вы, вероятно, достигли максимального тайм-аута диспетчера транзакций который установлен в machine.config. Если я правильно помню, если вы попытаетесь установить тайм-аут больше максимального значения, ваша настройка будет проигнорирована. Попробуйте увеличить значение в machine.config и посмотрите, поможет ли это в вашей проблеме.

Что касается случайных коммитов, устанавливаете ли вы Transaction Binding=Explicit Unbind в строке подключения? Значение по умолчанию - Transaction Binding=Implicit Unbind. Из MSDN:

Неявное отключение привязки приводит к отключению соединения от транзакции при ее завершении. После отключения дополнительные запросы на подключение выполняются в режиме автофиксации. Свойство System.Transactions.Transaction.Current не проверяется при выполнении запросов, пока транзакция активна. После завершения транзакции дополнительные запросы выполняются в режиме автоматической фиксации.

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

person Randy supports Monica    schedule 31.05.2011

Я хотел бы посмотреть, сможете ли вы использовать класс SqlBulkCopy. Это должно быть намного быстрее и может устранить необходимость в длительном тайм-ауте.

person Mitch Wheat    schedule 28.05.2011