In X++, maintaining transactional integrity is crucial to prevent data corruption and ensure the system performs reliably under concurrent usage. If proper safeguards aren’t used, issues like inconsistent data and poor scalability can arise.
X++ provides two important internal mechanisms to help preserve transactional integrity:
1. forUpdate Check
Ensures that a record can only be updated or deleted if it was explicitly selected for update.
Use the
forUpdate
keyword in theselect
statement or theselectForUpdate()
method on the table buffer to mark the record for update.
2. ttsLevel Check
Ensures that a record is updated or deleted within the same transaction scope in which it was selected for update.
This check prevents operations outside the appropriate transaction boundary.
Transaction Control Statements in X++
ttsBegin
Marks the start of a transaction. All data operations between ttsBegin
and ttsCommit
are treated as a single atomic unit. This helps ensure that partial updates don’t corrupt data.
ttsCommit
Ends and commits the current transaction. Once committed, changes are guaranteed to be persisted by the system.
ttsAbort
Rolls back all changes made in the current transaction, restoring the database to its previous state. Typically used when the user cancels the process or when a critical failure occurs.
Nested Transaction Example
X++ allows nested transactions. However, changes are only committed after the outermost ttsCommit
is successfully executed.
ttsBegin;
// Outer transaction
ttsBegin;
// Inner transaction
ttsCommit;
ttsCommit;
Practical Examples
Valid Update Using forUpdate and Transaction Block
CustTable custTable;
ttsBegin;
select forUpdate custTable where custTable.AccountNum == '5000';
custTable.CustGroup = '1';
custTable.update();
ttsCommit;
❌ Rejected by forUpdate Check (Missing forUpdate)
ttsBegin;
select myTable; // Error: Not selected for update
myTable.myField = 'xyz';
myTable.update();
ttsCommit;
❌ Rejected by ttsLevel Check (Wrong Transaction Scope)
ttsBegin;
select forUpdate * from myTable;
myTable.myField = 'xyz';
ttsCommit;
ttsBegin;
myTable.update(); // Error: Update outside original transaction
ttsCommit;
Summary
To maintain data consistency and system reliability in X++, always:
Use
forUpdate
when modifying records.Keep all select/update operations within the same transaction scope.
Use
ttsBegin
,ttsCommit
, andthrow
for safe transactional control.