Непонятное исключение из TransactionScope - PullRequest
4 голосов
/ 19 июня 2011

Я использую TransactionScrope в своем коде для выполнения команды 50 SQL на SQL Server 2008 R2.это пример моего кода:

   private void DoSomething()
    {
        bool IsComplete = false;
        SqlCommand sqlComm = null;
        //6 hours!!!
        TimeSpan ts1 = new TimeSpan(6, 0, 0);
        try
        {
            using (TransactionScope t = new TransactionScope(TransactionScopeOption.RequiresNew, ts1))
            {
                using (SqlConnection sqlConn = new SqlConnection(GetConnectionString()))
                {
                    //open sql connection
                    sqlConn.Open();
                    try
                    {
                        //create new sqlCommand
                        sqlComm = new SqlCommand();
                        for (int i = 1; i <= 2; i++)
                        {
                            IsComplete = true;
                            //This command takes 15 minutes
                            sqlComm.CommandText = "exec TestSp";
                            sqlComm.Connection = sqlConn;
                            sqlComm.CommandType = CommandType.Text;
                            sqlComm.CommandTimeout = 18000;
                            //Executing my command
                            int j = sqlComm.ExecuteNonQuery();
                            sw.WriteLine("Finsh Executing SQL Command:" + DateTime.Now.ToLongTimeString());
                            sw.Flush();
                        }
                        //End
                        IsComplete = true;
                    }
                    catch (Exception ex)
                    {
                        IsComplete = false;
                        string Message = ex.Message;
                    }
                    finally
                    {
                        if (sqlComm != null)
                            sqlComm.Dispose();
                        if (IsComplete)
                            t.Complete();
                    }
                }
            }
        }
        catch (Exception ex)
        {
            string messagee = ex.Message;
            //do something
        }
        finally
        {
            MessageBox.Show("Finsh");
        }
    }

Когда процедура занимает более 10 минут, я получаю следующее исключение:

Транзакция, связанная с текущим соединением, завершена, но имеетне был утилизирован.Транзакция должна быть удалена, прежде чем соединение можно будет использовать для выполнения операторов SQL.

Я устал от множества вариантов, меняя TimeSpam и меняя SqlCommand.Timout, но по какой-то причине я получаю это исключение.Исключение возникает после первого выполнения, которое занимает много времени.Например, если у меня 100 хранимых процедур и текстовых команд, и вся команда занимает менее 5 минут, и только одна команда занимает более 10 минут, выполнение следующей команды после длинной команды приведет к возникновению исключения.

Кто-нибудь понимает причину?

Спасибо за вашу помощь!

Ответы [ 3 ]

3 голосов
/ 04 апреля 2012

Эта ошибка может возникнуть, если транзакция выполняется дольше, чем maxTimeout для System.Transactions. Значение по умолчанию для maxTimeout составляет 10 минут.

Подробнее об этом можно прочитать в этом ответе: https://stackoverflow.com/a/10017056/205023 или в этом сообщении в блоге: http://thecodesaysitall.blogspot.se/2012/04/long-running-systemtransactions.html

3 голосов
/ 19 июня 2011

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

using(var tran = ...)
{
    bool isComplete;
    using(var conn = ...)
    {
         //...
    }

    if(isComplete)
        tran.Complete();
}

Также обратите внимание, что большинство раз, этопроще просто позволить обработке исключений обходить для нас Complete (), то есть

using(var tran = ...)
{
    using(var conn = ...)
    {
        //...
    }

    // if we get an exception, we won't get here
    tran.Complete();
}
1 голос
/ 21 октября 2011

Звучит так, будто транзакция просто перестает работать, видя, что она проваливается через установленное время.

...