When a transaction scope is committed and a record
set is inserted in the database table, the AOS assigns the inserted
record a unique record identifier. Record identifiers are also referred
to as record IDs, and RecID is the
column name. Record IDs are 64-bit integers that are used throughout the
application to ensure data integrity. MorphX automatically creates RecID
fields in all Dynamics AX application tables and system tables. Unlike
the IDs in normal fields, record IDs can’t be removed from the tables
because they are defined by the MorphX environment.
Note
The
transaction ID framework uses the same numbering scheme to identify
unique transactions across the application and within the company
accounts. It is also modified to use a 64-bit integer as the transaction
identifier. The approach in Dynamics AX 2009 is the same one used in
earlier versions of the application. |
The record ID allocation method uses a sequential
numbering scheme to allocate record identifiers to all rows inserted in
the Dynamics AX database. Sequential numbering isn’t strictly required
(numbers can be used out of sequence, manually modified, or skipped),
but duplicates aren’t allowed.
Allocation
The
AOS allocates record IDs as needed when a record is about to be
inserted in the database. Each AOS allocates blocks of 250 record IDs,
which are allocated per table. So each AOS holds an in-memory pool of up
to 249 record IDs per table. When the entire pool for a table is used,
the AOS allocates 250 new record IDs for that table.
There is no guarantee that records inserted in
the same table will have sequential record IDs if they are inserted by
different instances of the AOS. There is also no guarantee that the
sequence of record IDs will not be fragmented. Used record IDs are not
reclaimed when transactions are aborted. Unused record IDs are lost when
an AOS is stopped. Because of the 64-bit integer scheme, the available
number of record IDs is inexhaustible, and the fragmentation has no
practical impact.
The SystemSequences database table holds the next available record ID block for each table. A specific record for a table isn’t created in SystemSequences
until Dynamics AX inserts the first record into the specific table.
Keep in mind that the allocation of record IDs is not per company (as it
was in versions prior to Dynamics AX 4.0), but per table.
Inserted records always have a record ID, but they can also have a company account identifier (DataAreaID)
for grouping all data that belongs to a legal business entity. If data
in a table must be saved per company (meaning that the developer has set
the SaveDataPerCompany table property to Yes), the Dynamics AX application runtime always applies the DataAreaID column as part of every index and every database access command.
In Dynamics AX 2009, multiple instances of a
record ID within the same company are allowed as long as they don’t
occur within the same table. The coexistence of identical record IDs is
possible because the generator that creates the individual identifier
exists on a per-table basis, and the uniqueness of the record includes
the table ID in the reference. All companies share the same record ID
allocator per table, which ensures that only one instance of each record
ID exists across all companies within a particular table.
Figure 1 shows the differences in generation and allocation between Dynamics AX 2009 and versions prior to Dynamics AX 4.0.
In Dynamics AX 4.0, the record ID type changed
from 32-bit to 64-bit integer to prevent particularly high-volume
customers from running out of available record IDs. Another reason for
the change was to balance the requirements for maximum performance,
minimum impact on customer and partner extensions, database upgrade
time, and code upgrade time. The 64-bit integer enhancement allows for a
total of 18,446,744,073,709,551,615 (0xFFFF FFFF FFFF FFFF) record IDs
and provides more flexibility in allocating certain ranges for specific
purposes.
From Dynamics AX 4.0, the record ID range,
equivalent to the entire 32-bit range used in earlier versions, is
reserved to support existing customers when they upgrade. This approach
is the safest and most efficient model and can be implemented without
modifying any record IDs, including foreign key references to record
IDs. Only the content of the sequence number allocation table is
modified during upgrade. The range from 0x0000 0001 0000 0000 through
0x7FFF FFFF FFFF FFFF is used for new records after Dynamics 4.0 to
prevent possible conflict with data from previous versions.
Figure 2 illustrates the new allocation range for record IDs using the 64-bit integer, and it also shows where the SystemSequences
database table operates. The complete identifier range is essentially
divided into three groups (Upgrade Range Only, All New Record IDs, and
Reserved—Do Not Use), thus extending the existing record ID range of use
from 232 to 263 – 1 numbers.
Programming Model
The
kernel generates the record ID that the AOS allocates and assigns. In
two prominent scenarios, you might want the application code to
overwrite this behavior:
upgrade
The DB Upgrade Preparation tool uses the direct SQL statement to insert
data into the destination table from one or more source tables. In this
scenario, the record ID can be allocated up front for optimization. You
can also refactor the direct SQL statement by using INSERT_RECORDSET.
Performance optimization using constructs such as RecordInsertList and RecordSortedList
The application can use these two constructs to perform a bulk insert
operation. In addition, the application might want to maintain
referential integrity between the parent and the child table. For
example, assume that the application inserts more than one customer
record and the related customer transaction records. In such cases, the
related record ID (foreign key) of the customer transaction record is
the record ID of the customer record. To maintain this referential
integrity, your application code can preallocate record IDs and assign
them to the record buffers when using RecordInsertList/RecordSortedList to bulk insert records.
Dynamics AX offers a programming model to
preallocate record IDs in your application. The programming model has
been enhanced in Dynamics AX 2009 to have stricter control over
allocation and assignment.
The SystemSequence class exposes this programming model. This class has three methods you need to know and understand:
SuspendRecId
Suspends the record ID allocation for the table passed as a parameter.
The kernel no longer allocates a record ID automatically for this table
for the current session.
RemoveRecIdSuspension Releases the record ID allocation suspension for the table passed as a parameter for the current session.
ReserveValues
Reserves (preallocates) record IDs and returns the starting sequence
number for the application to use. The number of record IDs to allocate
is passed in as a parameter.
The following example shows how an application would use the SystemSequence class to preallocate record IDs.
static void RecidAllocationExample(Args _args)
{
CustTable customer;
SystemSequence sequence = new SystemSequence();
int64 sequenceStart;
int i = 0;
;
sequence.suspendRecIds(tablenum(CustTable));
sequenceStart = sequence.reserveValues(10, tablenum(CustTable));
sequence.removeRecIdSuspension(tablenum(CustTable));
ttsbegin;
while ( i < 10 )
{
customer.RecId = sequenceStart+i;
customer.accountNum = int2str(i);
customer.partyId = int2str(i);
customer.doInsert();
i++;
}
ttscommit;
}
|
If the application assigns a record ID without
suspending the record ID allocator, the system throws an exception. Once
the record ID allocation is suspended, the system raises an exception
if the application assigns a record ID that wasn’t reserved by that
session.
Administration
The Dynamics AX application runtime administers
the numbering scheme automatically, according to individual record IDs
and record ID blocks. The record IDs are managed in memory at the AOS
cache level, whereas the block allocation uses the SystemSequences
database to get information about the next record ID block value (NextVAL), native Dynamics AX table IDs (TabID), and the corresponding DataAreaID.
By default, the administration toolset provides very limited
manipulation possibilities for the database administrator, who can set
the next block value but can’t manipulate the next individually assigned
record ID. You can, however, use the SystemSequence system class to manually alter the automatic record ID assignment behavior, but only for local block assignment.
Caution
To avoid destruction of data integrity and to maintain the inter-table referencing, use the SystemSequence class with the utmost caution. |
The entities in the SystemSequences
table are not created when synchronizing the table definition from the
MorphX Data Dictionary, nor does the record ID block of 250 numbers get
allocated when starting the AOS. The entity is created the first time a
record is inserted into the table.
Upgrade
The enhanced record ID is based on a 64-bit
integer and requires existing 3.0 installations to upgrade. The upgrade
process for the record ID requires changes to the 3.0 application that
must be made before starting the application and data upgrade. The
Dynamics AX DB Upgrade Preparation tool handles the record ID data
pre-upgrade. However, some prerequisites must be met before you can use
the tool. Additionally, the existing application logic must be upgraded
to support the 64-bit integer.