Transaction Integrity

Microsoft Dynamics AX has two internal checking features to help ensure the integrity of transactions made by X++ programmers.

If the integrity of transactions is not ensured, it may lead to data corruption, or, at best, poor scalability with reference to concurrent users on the system.

This check ensures that no record can be updated or deleted if the record has not first been selected for update. A record can be selected for update, either by using the forUpdate keyword in the select statement, or by using the selectForUpdate method on tables.

This check ensures that no record can be updated or deleted except from within the same transaction scope as it was selected for update. Integrity is ensured by using the following statements:

  • ttsBegin: marks the beginning of a transaction. This ensures data integrity, and guarantees that all updates performed until the transaction ends (by ttsCommit or ttsAbort) are consistent (all or none).

  • ttsCommit: marks the successful end of a transaction. This ends and commits a transaction. MorphX guarantees that a committed transaction will be performed according to intentions.

  • ttsAbort: allows you to explicitly discard all changes in the current transaction. As a result, the database is rolled back to the initial state—nothing will have been changed. Typically, you will use this if you have detected that the user wants to break the current job. Using ttsAbort ensures that the database is consistent.

NoteNote

It is usually better to use exception handling instead of ttsAbort. The throw statement automatically aborts the current transaction.


Statements between ttsBegin and ttsCommit may include one or more transaction blocks as shown in the following example.

ttsBegin;

// Some statements.

ttsBegin;

// Statements.

ttsCommit;

ttsCommit;

In such cases, you should note that nothing is actually committed until the successful exit from the final ttsCommit.

Example use of ttsBegin and ttsCommit

Custtable custTable;
;
ttsBegin;
 
select forUpdate custTable where custTable.AccountNum == '4000';
custTable.NameAlias = custTable.Name;
custTable.update();
 
ttsCommit;

Examples of Code Rejected by the two Transaction Integrity Checks

ttsBegin;
 
select myTable; // Rejected by the forUpdate check.
mytable.myField = 'xyz';
myTable.update();
 
ttsCommit;
 
ttsBegin;
 
select forUpdate * from myTable;
myTable.myField = 'xyz';
ttsCommit;
...
ttsBegin;
myTable.update(); // Rejected by the ttsLevel check.
 
ttsCommit;

The first failure is because the forupdate keyword is missing.

The second failure is because the update is in another transaction scope rather than the one the that record was selected in ttsCommit for update.

Community Additions

ADD
Show: