我对X++有个问题。假设我有一个事务,它的伪代码如下所示
Custtable custTable;
ARandomTable mytable;
;
ttsBegin;
select forUpdate custTable where custTable.AccountNum == '4000';
custTable.NameAlias = custTable.Name;
custTable.update();
ttsBegin;
select forUpdate mytable where mytable.myField == 'abc';
mytable.myField = 'xyz';
mytable.update();
//ups something wrong happened... please abort the last
ttsAbort;
ttsCommit;为什么ttsAbort要中止整个事务而不是上次开始的事务?有什么办法可以避免吗?
发布于 2016-05-20 11:25:35
为什么ttsAbort要中止整个事务而不是上次开始的事务?
此行为确保使用第一个交易完整性启动的事务的ttsBegin。基本上,第一个ttsBegin就像这样说:“启动一个新事务,对于数据库,将事务中的所有内容都视为单个(原子)操作。如果您购买了ttsCommit (将对数据库执行操作)或ttsAbort (在数据库中不执行任何操作),事务就会结束。”
如果在第一个ttsBegin之后遇到另一个ttsBegin,这就像说:“对于第一个之后遇到的每个ttsBegin,忽略一个ttsCommit。”
由于事务被认为是单个原子操作,所以不能仅仅中止此操作的一部分。
有什么办法可以避免吗?
在你的情况下,没有。但是,有一种方法可以确保将事务的一部分提交到数据库,即使整个事务被中止。这是为内部事务使用单独的UserConnection来完成的。有关详细信息,请参阅如何使用UserConnection创建单独的事务,以确保事务不会在更高级别回滚。
发布于 2016-05-20 11:20:46
就像SQL ROLLBACK TRANSACTION一样,ttsAbort将所有语句回滚到最外层的事务中。
将显式或隐式事务回滚到事务的开始。
在AX/x++中,同样的规则适用于异常。
事务内的例外 如果在事务中抛出异常,事务将自动中止(发生ttsAbort操作)。这既适用于手动引发的异常,也适用于系统引发的异常。 当在ttsBegin - ttsCommit事务块中抛出异常时,该事务块内的catch语句无法处理该异常。相反,位于事务块之外的最内部的catch语句是要测试的第一个catch语句。
https://stackoverflow.com/questions/37344861
复制相似问题