IT tutorials
 
Technology
 

Microsoft Dynamic AX 2009 : .Performance (part 2) - Transaction Performance - Set-Based Data Manipulation Operators - The insert_recordset Operator

10/28/2013 3:34:42 AM
- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

3. Transaction Performance

In the preceding section, we focused on limiting traffic between the client and server tiers. When a Dynamics AX application is executed, however, these tiers are just two of the three tiers involved. The third tier is the database tier. You need to optimize the exchange of packages between the server tier and the database tier, just as you do between the client and server tiers. In this section, we explain how you can optimize the transactional part of the execution of application logic. The Dynamics AX application runtime helps you minimize calls made from the server tier to the database tier by supporting set-based operators and data caching. However, you should also do your part by reducing the amount of data you send from the database tier to the server tier. The less data you send, the faster that data is fetched from the database. Fewer packages are sent back as well. These reductions result in less memory consumed. All these efforts promote faster execution of application logic, which results in smaller transaction scope, less locking and blocking, and improved concurrency and throughput.

3.1 Set-Based Data Manipulation Operators

The X++ language contains specific operators and classes to enable set-based manipulation in the database. The set-based constructs have an advantage over record-set constructs—they make fewer round-trips to the database. The following X++ code example, which shows the selection of several custTable records, each updated with a new value in the creditMax field, illustrates that a round-trip is required for the execution of the select statement and for each execution of update.

static void UpdateCustomers(Args _args)
{
CustTable custTable;
;
ttsbegin;

while select forupdate custTable
where custTable.CustGroup == '20' // Round trip to database
{
custTable.CreditMax = 1000;
custTable.update(); // Round trip to database
}

ttscommit;
}


In a scenario in which 100 custTable records qualify for the update because the custGroup field equals 20, the number of round-trips would be 1 select + 100 updates = 101 round-trips.

The number of round-trips for the select statement might be slightly higher, depending on the number of custTable records that can be retrieved simultaneously from the database and sent to the AOS.

Theoretically, you could rewrite the preceding scenario to result in only one round-trip to the database by changing the X++ code as indicated in the following example. The example shows how to use the update_recordset operator, resulting in a single SQL UPDATE statement being parsed to the database.

static void UpdateCustomers(Args _args)
{
CustTable custTable;
;
ttsbegin;

update_recordset custTable setting creditMax = 1000
where custTable.CustGroup == '20'; // Single round trip to database
ttscommit;
}


For several reasons, however, using a custTable record buffer doesn’t result in only one round-trip. We explain why in the following subsections on the set-based constructs supported by the Dynamics AX application runtime. In these sections, we also describe features available that allow you to modify the preceding scenario to ensure a single round-trip to the database, even when you’re using a custTable record buffer.

Important

None of the following set-based operations improves performance when used on temporary tables. The Dynamics AX application runtime always downgrades set-based operations on temporary tables to record-based operations. This downgrading happens regardless of how the table became a temporary table (whether specified in metadata in the table’s properties, disabled because of the configuration of the Dynamics AX application, or explicitly stated in the X++ code using the table). Also, the downgrade by the application runtime always invokes the doInsert, doUpdate, and doDelete methods on the record buffer, so no application logic in the overridden methods is executed.


3.1.1 The insert_recordset Operator

The insert_recordset operator enables the insertion of multiple records into a table in one round-trip to the database. The following X++ code illustrates the use of insert_recordset as the code copies sizes from one item to another item. The item to which the sizes are copied is selected from inventTable.

static void CopySizes(Args _args)
{
InventSize inventSizeTo;
InventSize inventSizeFrom;
InventTable inventTable;
;
ttsbegin;
insert_recordset inventSizeTo (ItemId, InventSizeId, Description, Name)
select itemId from inventTable
where inventTable.ItemId == '1000'
join inventSizeId, description, name from inventSizeFrom
where inventSizeFrom.ItemId == '1002';
ttscommit;
}


The round-trip to the database involves the execution of three statements in the database:

  • The select part of the insert_recordset statement is executed where the selected rows are inserted into a temporarily created new table in the database. The syntax of the select statement when executed in Microsoft SQL Server is similar to SELECT <field list> INTO <temporary table> FROM <source tables> WHERE <predicates>.

  • The records from the temporary table are inserted directly into the target table using syntax such as INSERT INTO <target table> (<field list>) SELECT <field list> FROM <temporary table>.

  • The temporary table is dropped with the execution of DROP TABLE <temporary table>.

This approach has a tremendous performance advantage over inserting the records one by one, as shown in the following X++ code, which addresses the same scenario as the preceding X++ code.

static void CopySizes(Args _args)
{
InventSize inventSizeTo;
InventSize inventSizeFrom;
InventTable inventTable;
;
ttsbegin;
while select itemId from inventTable
where inventTable.ItemId == '1000'
join inventSizeId, description, name from inventSizeFrom
where inventSizeFrom.ItemId == '1002'
{
inventSizeTo.ItemId = inventTable.ItemId;
inventSizeTo.InventSizeId = inventSizeFrom.InventSizeId;
inventSizeTo.Description = inventSizeFrom.Description;
inventSizeTo.Name = inventSizeFrom.Name;
inventSizeTo.insert();
}
ttscommit;
}


If 10 sizes were copied, this scenario would result in 1 round-trip caused by the select statement and an additional 10 round-trips caused by the inserts, totaling 11 round-trips.

The insert_recordset operation could be downgraded, however, from a set-based operation to a record-based operation. The operation is downgraded if any of the following conditions is true:

  • The table is entire-table cached.

  • The insert method or the aosValidateInsert method is overridden on the target table.

  • Alerts have been set to be triggered by inserts into the target table.

  • The database log has been configured to log inserts into the target table.

  • Record level security (RLS) is enabled on the target table. If RLS is enabled only on the source table or tables, insert_recordset isn’t downgraded to row-by-row operation.

The Dynamics AX application runtime automatically handles the downgrade and internally executes a scenario similar to the while select scenario shown in the preceding example.

Important

When the Dynamics AX application runtime checks for overridden methods, it determines only whether the methods are implemented. It doesn’t determine whether the overridden methods contain only the default X++ code. A method is therefore considered to be overridden by the application runtime even though it contains the following X++ code.

public void insert()
{
super;
}


Any set-based insert is then downgraded. You need to remember to delete such a method to avoid the downgrade, with its performance ramifications.


If a table is not entire-table cached, however, you can avoid any downgrade caused by the previously mentioned functionality. The record buffer contains methods that turn off the checks that the application runtime performs when determining whether to downgrade the insert_recordset operation.

  • Calling skipDataMethods(true) prevents the check that determines whether the insert method is overridden.

  • Calling skipAosValidation(true) prevents the check on the aosValidateInsert method.

  • Calling skipDatabaseLog(true) prevents the check that determines whether the database log is configured to log inserts into the table.

  • Calling skipEvents(true) prevents the check that determines whether any alerts have been set to be triggered by the insert event on the table.

The following X++ code, which includes the call to skipDataMethods(true), ensures that the insert_recordset operation is not downgraded because the insert method is overridden on the InventSize table.

static void CopySizes(Args _args)
{
InventSize inventSizeTo;
InventSize inventSizeFrom;
InventTable inventTable;
;
ttsbegin;
inventSizeTo.skipDataMethods(true); // Skip override check on insert.
insert_recordset inventSizeTo (ItemId, InventSizeId, Description, Name)
select itemId from inventTable
where inventTable.ItemId == '1000'
join inventSizeId, description, name from inventSizeFrom
where inventSizeFrom.ItemId == '1002';
ttscommit;
}


You must use skip methods with extreme caution because they can lead to the logic in the insert method not being executed, events not being raised, and potentially, the database log not being written to. If you override the insert method, you should use the cross-reference system to determine whether any X++ code calls skipDataMethods(true). If you don’t, the X++ code could fail to execute the insert method. Moreover, when you implement calls to skipDataMethods(true), make sure that not executing the X++ code in the overridden insert method won’t lead to data inconsistency.

Skip methods can be used only to influence whether the insert_recordset operation is downgraded. If a call to skipDataMethods(true) is implemented to prevent downgrading because the insert method is overridden, the overridden version of the insert method will eventually be executed if the operation is still downgraded. The operation would be downgraded, if, for example, the database log had been configured to log inserts into the table. In the previous example, the overridden insertInventSize table would be executed if the database log were configured to log inserts into the InventSize table because the insert_recordset operation would then revert to a while select scenario in which the overridden insert method would get called. method on the

Dynamics AX 2009 introduces support for literals in insert_recordset. The literal support for insert_recordset was introduced primarily to support upgrade scenarios in which the target table is populated with records from one or more source tables (using joins) and one or more columns in the target table need to be populated with a literal value that doesn’t exist in the source. The following code example illustrates the usage of literals in insert_recordset.

static void InsertRecordSetLiteralExample(Args _args)
{
CusttTable customer;
CustTable custTable;
boolean flag = boolean::false;
;

ttsbegin;
insert_recordset
customer
(
Name,
Active
)
select
Name,
flag
from
custTable;
ttscommit;
}
 
Others
 
- Microsoft Dynamic AX 2009 : .Performance (part 1) - Reducing Round-Trips Between the Client and the Server
- Exchange Server 2010 Quick Start Guide : Configuring Recipients (part 3) - Configuring a Postmaster Address, SSL Certificate , Entering the Product Key
- Exchange Server 2010 Quick Start Guide : Configuring Recipients (part 2) - Creating Distribution Groups, Organizational Health
- Exchange Server 2010 Quick Start Guide : Configuring Recipients (part 1)
- Sharepoint 2010 : Data Access Overview - Performance
- Sharepoint 2010 : Data Access Overview - Lists and Document Libraries
- Sharepoint 2010 : Data Access Overview - Columns (part 3) - Field Types - Inheriting from BaseFieldControl
- Sharepoint 2010 : Data Access Overview - Columns (part 2) - Field Types - Inheriting from SPField
- Sharepoint 2010 : Data Access Overview - Columns (part 1)
- Sharepoint 2010 : Data Access Overview - Content Types (part 3) - Enterprise Content Types
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
Technology FAQ
- Is possible to just to use a wireless router to extend wireless access to wireless access points?
- Ruby - Insert Struct to MySql
- how to find my Symantec pcAnywhere serial number
- About direct X / Open GL issue
- How to determine eclipse version?
- What SAN cert Exchange 2010 for UM, OA?
- How do I populate a SQL Express table from Excel file?
- code for express check out with Paypal.
- Problem with Templated User Control
- ShellExecute SW_HIDE
programming4us programming4us