X++ ttsbegin 和 ttsAbort
X++ ttsbegin and ttsAbort
我对 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 中止整个事务而不是上次开始的事务?有什么办法可以避免吗?
就像SQLROLLBACK TRANSACTION
ttsAbort
将所有语句回滚到最外层事务。
Rolls back an explicit or implicit transaction to the beginning of the transaction
在 AX/x++ 中,同样的规则适用于例外情况。
Exceptions Inside Transactions
If an exception is thrown inside a transaction, the transaction is automatically aborted (a ttsAbort operation occurs). This applies both for exceptions thrown manually and for exceptions thrown by the system.
When an exception is thrown inside a ttsBegin - ttsCommit transaction block, no catch statement inside that transaction block can process the exception. Instead, the innermost catch statements that are outside the transaction block are the first catch statements to be tested.
Why does the ttsAbort abort the whole transaction and not the one that
was last begun?
此行为确保从第一个 ttsBegin
开始的事务的 transaction integrity。基本上这第一个 ttsBegin
就像在说:"Start a new transaction and with regards to the database consider everything in this transaction as a single (atomic) action. The transaction ends if you ecounter a ttsCommit
(upon which the action will be executed against the database) or a ttsAbort
(upon nothing will be done in the database)."
如果在第一个ttsBegin
之后遇到另一个ttsBegin
,这就像在说:"For each ttsBegin
you encounter after the first, ignore one ttsCommit
."
由于事务被视为单个原子操作,因此您不能只中止该操作的一部分。
Is there a way to avoid it?
在你的情况下,没有。但是,有一种方法可以确保将事务的一部分提交给数据库,即使整个事务中止也是如此。这是通过为内部事务使用单独的 UserConnection
来完成的。请参阅 如何使用 UserConnection 创建单独的事务以确保您的事务不会在更高级别回滚
获取更多信息。
我对 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 中止整个事务而不是上次开始的事务?有什么办法可以避免吗?
就像SQLROLLBACK TRANSACTION
ttsAbort
将所有语句回滚到最外层事务。
Rolls back an explicit or implicit transaction to the beginning of the transaction
在 AX/x++ 中,同样的规则适用于例外情况。
Exceptions Inside Transactions
If an exception is thrown inside a transaction, the transaction is automatically aborted (a ttsAbort operation occurs). This applies both for exceptions thrown manually and for exceptions thrown by the system.
When an exception is thrown inside a ttsBegin - ttsCommit transaction block, no catch statement inside that transaction block can process the exception. Instead, the innermost catch statements that are outside the transaction block are the first catch statements to be tested.
Why does the ttsAbort abort the whole transaction and not the one that was last begun?
此行为确保从第一个 ttsBegin
开始的事务的 transaction integrity。基本上这第一个 ttsBegin
就像在说:"Start a new transaction and with regards to the database consider everything in this transaction as a single (atomic) action. The transaction ends if you ecounter a ttsCommit
(upon which the action will be executed against the database) or a ttsAbort
(upon nothing will be done in the database)."
如果在第一个ttsBegin
之后遇到另一个ttsBegin
,这就像在说:"For each ttsBegin
you encounter after the first, ignore one ttsCommit
."
由于事务被视为单个原子操作,因此您不能只中止该操作的一部分。
Is there a way to avoid it?
在你的情况下,没有。但是,有一种方法可以确保将事务的一部分提交给数据库,即使整个事务中止也是如此。这是通过为内部事务使用单独的 UserConnection
来完成的。请参阅 如何使用 UserConnection 创建单独的事务以确保您的事务不会在更高级别回滚
获取更多信息。