Время ожидания транзакции истекло при использовании Linq2Sql DataContext.SubmitChanges()

пожалуйста, помогите мне решить эту проблему:

Существует внешняя транзакция MSMQ. Я пытаюсь использовать новую транзакцию для ведения журнала, но получаю следующую ошибку при попытке отправить изменения: «Время ожидания истекло. Время ожидания истекло до завершения операции или сервер не отвечает». Вот код:

public static void SaveTransaction(InfoToLog info)
    {
        using (TransactionScope scope =
            new TransactionScope(TransactionScopeOption.RequiresNew))
        {
            using (TransactionLogDataContext transactionDC =
                        new TransactionLogDataContext())
            {
                transactionDC.MyInfo.InsertOnSubmit(info);

                transactionDC.SubmitChanges();
            }

            scope.Complete();
        }
    }

Пожалуйста помогите. Спасибо.


person spkenny    schedule 13.04.2009    source источник


Ответы (2)


Вы можете рассмотреть возможность увеличения тайм-аута или полного его устранения.

Что-то типа:

using(TransactionLogDataContext transactionDC = new TransactionLogDataContext())
{
    transactionDC.CommandTimeout = 0;  // No timeout.
}

Будь осторожен

person billb    schedule 13.04.2009
comment
Спасибо. но это решение ставит новый вопрос: если область транзакции была изменена, почему операция отправки становится такой трудоемкой? База данных и приложение находятся на одном компьютере. - person spkenny; 13.04.2009
comment
У меня недостаточно информации, чтобы ответить на этот вопрос. Вы можете рассмотреть возможность использования SQL Profiler, чтобы увидеть, что происходит за кулисами. Удачи. - person billb; 13.04.2009

Вы сказали:

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

Это потому, что вы создаете новый DataContext прямо здесь:

TransactionLogDataContext transactionDC = new TransactionLogDataContext()) 

С новым контекстом данных ADO.NET открывает новое соединение (даже если строки соединения одинаковы, если только вы не используете умный пул соединений). В контексте транзакции, когда вы пытаетесь работать с более чем 1 экземпляром подключения (что вы только что сделали), ADO.NET автоматически повышает транзакцию до распределенной транзакции и пытается закрепить ее в MSDTC. Зачисление самой первой транзакции на соединение в MSDTC займет время (у меня это занимает 30+ секунд), однако последовательные транзакции будут быстрыми (в моем случае 60 мс). Взгляните на этот http://support.microsoft.com/Default.aspx?id=922430

Что вы можете сделать, так это повторно использовать транзакцию и строку подключения (если возможно) при создании нового DataContext.

 TransactionLogDataContext tempDataContext = 
      new TransactionLogDataContext(ExistingDataContext.Transaction.Connection);
 tempDataContext.Transaction = ExistingDataContext.Transaction;

Где ExistingDataContext — это тот, который начал внешнюю транзакцию.

Или попытайтесь ускорить ваш MS DTC.

Также используйте SQL Profiler, предложенный billb, и найдите SessionId между различными командами (сохраните и сохраните журнал в вашем случае). Если SessionId изменится, вы фактически используете 2 разных соединения, и в этом случае вам придется повторно использовать транзакцию (если вы не хотите, чтобы она повышалась до MS DTC).

person Ivan    schedule 08.06.2010