C # - TransactionScope - TransactionAbortedException - транзакция прервана - PullRequest
0 голосов
/ 31 января 2012

У меня есть такой код:

class Importer 
{
    private DatabaseContext m_context;

    public: Importer() 
    {
        m_context = new DatabaseContext();
        m_context.CommandTimeout = 5400; //This is seconds
    }

    public bool Import (ref String p_outErrorMsg) 
    {
        List<SomeData> dataToImport = new List<SomeData>();
        getSomeData(ref dataTiImport);

        bool result = false;

        try 
        {
            using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(2, 0, 0))) 
            { //Two hours timeout
                result = importDatas(dataToImport);
                if (result == true) 
                {
                    scope.Complete();
                }
            }
        } 
        catch (TransactionAbortedException ex)
        {
            p_outErrorMsg = String.Format("TransactionAbortedException Message: {0}", ex.Message);
        } 
        catch (ApplicationException ex) 
        {
            p_outErrorMsg = String.Format("ApplicationException Message: {0}", ex.Message);
        }
    }

    bool importDatas(List<SomeData> p_DataToImport) 
    {
        foreach (SomeData data in p_DataToImport) 
        { //There can be somehitg about 3000 iterations
            if (!importSimpleData(data)) 
            {
                return false;
            }
            return true;
        }
    }

    bool importSimpleData(SomeData p_Data) 
    {
        //creation some object o1
        try 
        {
            m_context.objetc1s.InsertOnSubmit(o1);
            m_context.SubmitChanges();
        }
        catch (Exception e) 
        {
            //Error handlig
            return false
        }

        //creation some object o2
        o2.id_o1 = o1.id_o1;
        try 
        {
            m_context.objetc2s.InsertOnSubmit(o2);
            m_context.SubmitChanges();
        } 
        catch (Exception e) 
        {
            //Error handlig
            return false
        }

        //creation some object o3
        o3.id_o2 = o2.id_o2;
        try 
        {
            m_context.objetc3s.InsertOnSubmit(o3);
            m_context.SubmitChanges();
        } 
        catch (Exception e) 
        {
            //Error handlig
            return false
        }

        //creation some object o4
        o4.id_o1 = o1.id_o1;
        try 
        {
            m_context.objetc4s.InsertOnSubmit(o4);
            m_context.SubmitChanges();
        } 
        catch (Exception e) 
        {
            //Error handlig
            return false
        }

        return true;
    }
}

И если в List есть 500 записей, все пишется нормально.Но когда список близок к 1000, у меня всегда есть исключение: TransactionAbortedException.Message = "транзакция прервана".

Во-первых, я думаю, что тайм-аут был маленьким, поэтому я представил код для этих двух строк:... m_context.CommandTimeout = 5400;// Это секунды (1,5 часа) ... using (TransactionScope scope = new TransactionScope (TransactionScopeOption.Required, new TimeSpan (2, 0, 0))) {// Тайм-аут двух часов ...

Как вы можете видеть в приведенном выше коде.

По-прежнему происходит то же исключение, я что-то упустил?Что я делаю неправильно?Я должен добавить, что база данных является удаленной (не локальной)

Заранее спасибо за помощь!

Ответы [ 2 ]

1 голос
/ 09 июля 2013

Мне придется снова выкопать документацию, но установка таймаута транзакции на 2 часа может не произойти для вас.Существует ограничение на время ожидания транзакции, которое истекает через machine.config, и если вы укажете больше, чем ограничение, оно тихо игнорирует вас.

Я столкнулся с этим давным-давно и обнаружилоснованный на отражении способ настройки этого параметра здесь Мэттом Ханикаттом , чтобы убедиться, что вы действительно получаете указанное вами время ожидания.

0 голосов
/ 31 января 2012

Похоже, что importSimpleData не выполняется в некоторой строке, а importData возвращает false. В таком случае вы не звоните scope.Complete(), и это причина, по которой транзакция откатывается.

...