C# - TransactionScope - TransactionAbortedException - 事务已中止

时间:2012-01-31 07:52:29

标签: c# transactionscope

我的代码是这样的:

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 个答案:

答案 0 :(得分:1)

我必须再次挖掘文档,但是可能不会将事务超时设置为2小时 。关于通过machine.config降低事务超时的时间有一个上限,如果你指定了超过那个上限,它会悄悄地忽略你。

我很久以前遇到过这个问题,并找到了一种基于反射的方法来调整设置here by Matt Honeycutt,以确保你真正得到你指定的超时。

答案 1 :(得分:0)

似乎importSimpleData在某些行上失败,而importData返回false。在这种情况下,您不会调用scope.Complete(),这就是事务回滚的原因。