堆栈跟踪:在没有先调用TTSBEGIN的情况下调用TTSCOMMIT

时间:2015-01-27 15:18:41

标签: transactions axapta x++ dynamics-ax-2012

我们在某些表方法的某些插入/更新/删除调用中遇到了这个奇怪的错误,其中这些方法中还有一些其他代码也在AX中使用ttsbegin / ttscommit 2012年功能包。

ttsbeginttscommit在所有级别上均衡,并在代码中使用它们的每个位置在相同级别上声明。

我发现这种行为非常奇怪,因为相同的代码在另一个具有相同规范的环境中工作。

这可能与内核有关吗?

例如,在CustTable表单上删除多行时,有时会发生相同的错误。知道它可能是什么?

3 个答案:

答案 0 :(得分:2)

作为与try-catch结合的交易的一般信息:

  

一般规则是异常被捕获在最外层   catch,ttslevel为0.这意味着如果你把一个   围绕try / catch的事务,您的异常将不会被捕获。   以下两个工作表明:

     

try / catch中的事务:       尝试       {           ttsBegin;           抛出错误("错误");           ttsCommit;       }       抓住       {
          info("错误捕获");       }

     

输出:

Error an error
Info error caught
     

尝试/捕获内部事务:       ttsBegin;       尝试       {           抛出错误("错误");
      }       抓住       {
          info("错误捕获");       }       ttsCommit;

     

输出:

Error an error
     

如您所见,事务发生时未捕获错误   试试看。

     

但是,此规则有两个例外。以下代码   演示了UpdateConflict和DupplicateKeyException可以   陷入交易中。       Set set = new Set(Types :: Enum); //包含所有可能异常的集合       SetEnumerator se; //枚举器用于循环遍历异常集       例外例外; //用于从集合中转换值       boolean caughtInside;       ;

// add all exception to a set
set.add(Exception::Break);
set.add(Exception::CLRError);
set.add(Exception::CodeAccessSecurity);
set.add(Exception::DDEerror);
set.add(Exception::Deadlock);
set.add(Exception::DuplicateKeyException);
set.add(Exception::DuplicateKeyExceptionNotRecovered);
set.add(Exception::Error);
set.add(Exception::Info);
set.add(Exception::Internal);
set.add(Exception::Numeric);
set.add(Exception::PassClrObjectAcrossTiers);
set.add(Exception::Sequence);
set.add(Exception::Timeout);
set.add(Exception::UpdateConflict);
set.add(Exception::UpdateConflictNotRecovered);
set.add(Exception::Warning);

// create enumerator
se = set.getEnumerator();

// loop all exceptions
while(se.moveNext())
{
    // set flag false
    caughtInside = false;
    // begin outer try catch
    try
    {
        ttsBegin;
        // begin inner try catch
        try
        {
            // cast exception
            exception = se.current();
            // trhow exception
            throw exception;
        }
        catch
        {
            // set flag to indicate the exception was caught inside the transaction
            caughtInside = true;

            warning(strFmt("%1 can be caught inside transaction", exception));
            // throw exception again to catch it outside of transaction
            throw exception;
        }
        ttsCommit;
    }
    catch
    {
        // for once, it's ok to catch everyting :)  

        if(caughtInside)
        {
            warning(strFmt("%1 can also be caught outside of the transaction", exception));
        }
        else
        {
            info(strFmt("%1 can only be caught outside of the transaction", exception));
        }

    }
}
     

输出:

Info Info can only be caught outside of the transaction
Info Warning can only be caught outside of the transaction
Info Deadlock can only be caught outside of the transaction
Info Error can only be caught outside of the transaction
Info Internal can only be caught outside of the transaction
Info Break can only be caught outside of the transaction
Info DDEerror can only be caught outside of the transaction
Info Sequence can only be caught outside of the transaction
Info Numeric can only be caught outside of the transaction
Info CLRError can only be caught outside of the transaction
Info CodeAccessSecurity can only be caught outside of the transaction
Warning UpdateConflict can be caught inside transaction
Warning UpdateConflict can also be caught outside of the transaction
Info UpdateConflictNotRecovered can only be caught outside of the transaction
Warning DuplicateKeyException can be caught inside transaction
Warning DuplicateKeyException can also be caught outside of the transaction
Info DuplicateKeyExceptionNotRecovered can only be caught outside of the transaction
Info Timeout can only be caught outside of the transaction
Info PassClrObjectAcrossTiers can only be caught outside of the transaction 
     

值得注意的是,当你进入一个catch区块时,就有了   这是一个隐含的ttsabort,因此事务已经回滚。   但是,对于UpdateConflict和DuplicateKeyException,情况并非如此   当他们陷入交易中时。

来源:http://www.artofcreation.be/2011/08/10/try-catch-and-transactions/

答案 1 :(得分:0)

returnttsbegin之间拨打ttscommit是不行的。

此外,问题可能是由代码fx insertupdate方法调用的任何代码中引入的任何不平衡引起的。

答案 2 :(得分:0)

我现在已经在代码中对错误进行了本地化。在第5个ttslevel的代码内部,在VAR层中的ContactPerson表的插入方法中有一个自定义..我知道它非常奇怪,但我们新近取代了这个客户,所以这显然是一个管理不善的测试环境的标志。删除一个TTSCOMMIT后,很多东西显然已经开始工作了。这是我在论坛上的第一篇文章,我对你们给我的回应印象深刻。我非常感谢你们对这个案子给予的一切帮助。我希望以后再回复一些:)