IT tutorials
 
Technology
 

Microsoft Dynamic AX 2009 : .Performance (part 1) - Reducing Round-Trips Between the Client and the Server

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

1. Introduction

Performance is often an afterthought. Many development teams rarely pay attention to performance until late in the development process or, more critically, after a customer reports severe performance problems in a production environment. After a feature is implemented, making more than minor performance improvements is often too difficult. But if you know how to use the performance-optimization features in Dynamics AX, you can create designs that allow for optimal performance within the boundaries of the Dynamics AX development and runtime environments.


2. Client/Server Performance

Client/server communication is one of the key areas of optimization for Dynamics AX. In this section, we detail the best practices, patterns, and programming techniques that yield optimal communication between the client and the server.

2.1 Reducing Round-Trips Between the Client and the Server

The following three techniques can cover between 50 and 80 percent of round-trips in most scenarios:

  • Use CacheAddMethod for all display and edit methods on a form.

  • Refactor RunBase classes to support marshaling of the dialog between client and server.

  • Properly index tables.

CacheAddMethod

Display and edit fields are used on forms to display data that must be derived or calculated based on other information in the table. They can be written on either the table or the form. By default, these fields are calculated one by one, and if there is any need to go to the server during one of these methods, as there usually is, each of these functions goes to the server individually. These fields are recalculated every time a refresh is triggered on the form, which can originate from editing fields, using menu items, or the user requesting a form refresh. Such a technique is expensive both from a round-tripping perspective as well as in the number of calls it places to the database from the Application Object Server (AOS).

For display and edit fields declared in the form’s Data Source, no caching can be performed because the fields need access to the form metadata. If possible, you should move these methods to the table. For display and edit fields declared on a table, you have to use FormDataSource.CacheAddMethod to enable caching. This method allows the form’s engine to calculate all the necessary fields in one round-trip to the server and then to cache the results from this call. To use cacheAddMethod, in the init method of a Data Source that uses display or edit methods, call cacheAddMethod on that Data Source, passing in the method string for the display or edit method. For an example of this, look at the SalesTable form’s SalesLine Data Source. In the init method, you find the following code.

public void init()
{


super();


salesLine_ds.cacheAddMethod(tablemethodstr(SalesLine, invoicedInTotal));


salesLine_ds.cacheAddMethod(tablemethodstr(SalesLine, deliveredInTotal));


salesLine_ds.cacheAddMethod(tablemethodstr(SalesLine, reservedPhysicalInSalesUnit));


salesLine_ds.cacheAddMethod(tablemethodstr(SalesLine, reservedOnOrderInSalesUnit));


salesLine_ds.cacheAddMethod(tablemethodstr(SalesLine, onOrderInSalesUnit));


salesLine_ds.cacheAddMethod(tablemethodstr(SalesLine, qualityOrderStatusDisplay));


}



If this code is commented out, each of these display methods is computed for every operation on the form Data Source, thus increasing the number of round-trips to the server as well as the number of calls to the database server.

For Dynamics AX 2009, Microsoft made a significant investment in the CacheAddMethod infrastructure. In previous releases, this worked only for display fields, and only on form load. In Dynamics AX 2009, the cache is used for both display and edit fields, and is used throughout the lifetime of the form, including reread, write, refresh, and any other method that reloads the data behind the form. On all these methods, the fields are refreshed, but the kernel now refreshes them all at once rather than individually, as it did in previous versions of Dynamics AX.

RunBase Technique

RunBase classes form the basis for most business logic inside of Dynamics AX. RunBase provides much of the basic functionality needed to perform a business process, such as displaying a dialog, running the business logic, and running the business logic in batches. When business logic executes through RunBase, the logic flows as shown in Figure 1.

Figure 1. RunBase communication pattern


Most of the round-trip problems of RunBase originate with the dialog. The RunBase class should be running on the server for security reasons as well as for the fact that it is accessing lots of data from the database and writing it back. A problem occurs when the RunBase class itself is marked to run on the server. When the RunBase class is running on the server, the dialog is created and driven from the server, causing an immense number of round-trips between the client and the server.

To avoid excessive round-trips, mark the RunBase class to run on Called From, meaning that it will run on either tier, and then mark either the construct method for the RunBase class or the menu item to run on the server. Called From enables the RunBase framework to marshal the class back and forth between the client and the server without having to drive the dialog from the server, significantly reducing the round-trips needed across the application. Keep in mind that you must implement the pack and unpack methods in a way that allows this serialization to happen.

For an example of the RunBase class, examine the SalesFormLetter class in the base application. For an in-depth guide to implementing RunBase to optimally handle round-trips between the client and the server, refer to the Microsoft Dynamics AX 2009 White Paper, “RunBase Patterns,” which you can find at the Microsoft Download Center.

Caching and Indexing

Dynamics AX has a data caching framework on the client that can help you greatly reduce the number of times the client goes to the server. In previous releases of Dynamics AX, this cache operated only on primary keys. In Dynamics AX 2009, this cache has been moved and now operates across all the unique keys in a table. Therefore, if a piece of code is accessing data from the client, the code should use a unique key if possible. Also, you need to ensure that all keys that are unique are marked as such in the Application Object Tree (AOT). You can use the Best Practices tool to ensure that all your tables have a primary key.

Properly setting the CacheLookup property is a prerequisite for using the cache on the client. Table 1 shows the values that CacheLookup can have.

Table 1. Table Cache Definitions
Cache SettingDescription
FoundIf a table is accessed by a primary key or a unique index, the value is cached for the duration of the session or until the record is updated. If another AOS updates this record, all AOSs will flush their cache. This cache setting is appropriate for master data.
NotInTTSSame as Found except every time a transaction is started, the cache is flushed and the query goes to the database. This cache setting is appropriate for transactional tables.
FoundAndEmptySame as Found except if the query fails to find a record, the absence of the record is stored. This cache setting is appropriate for region-specific master data or master data that isn’t always present.
EntireTableThe entire table is cached in memory on the AOS, and the client treats this cache as “Found.” This cache setting is appropriate for tables with a known number of limited records, such as parameter tables.
NoneNo caching occurs. This setting is appropriate in only a few cases, such as when optimistic concurrency control has to be disabled.

When caching is set, the client stores up to 100 records per table, and the AOS stores up to 2000 records per table.

Index caching works only if the where clause has column names that are unique. In other words, caching won’t work if a join is present, if the query is a cross-company query, or if any range operations are in the query. Therefore, if you’re checking whether a query record that has a particular primary key and some other attribute exists, search the database only by primary key. For an example of this, refer to xDataArea.isVirtualCompany.

static boolean isVirtualCompany(DataAreaId dataAreaId)
{
DataArea dataArea1;

boolean fRetVal;
;
fRetVal=FALSE;
select Id,isVirtual from dataArea1 where dataArea1.Id == dataAreaId;
if(dataArea1.Id && dataArea1.isVirtual==1)
{
fRetVal=TRUE;
}
return fRetVal;
}


Notice that this code queries the database by ID and then the primary key, and then it checks the virtual company in memory. This operates at around the same speed but allows the query to hit the cache and the result of the query to be cached on both the client and server tiers.

EntireTable caches store the entire contents of a table on the server, but the cache is treated as a “Found” cache on the client. For tables that have only one row per company, such as parameter tables, you should add a key column that always has a known value, such as 0. This allows the client to use the cache when accessing these tables. An example of the use of a key column in the base application (i.e., Dynamics AX 2009 without any customizations) is CustParameters table.

2.2 Writing Tier-Aware Code

When you’re writing code, you should be aware of what tier the code is going to run on and what tier the objects you’re accessing are on. Objects that have their RunOn property set to Server/Client/Called From are always instantiated on the server. Objects that are marked to RunOn Client are always instantiated on the client, and Called From is instantiated wherever the class is created. One caveat: if you mark classes to RunOn either the client or the server, you can’t serialize them to another tier via pack and unpack. If you attempt to serialize a server class to the client, all you get is a new object on the server with the same values. Static methods run on whatever tier they are specified to run on via the Client, Server, or Client Server keyword in the declaration.

Working with Temp Tables

Temp tables can be a common source of both client callbacks and calls to the server. Unlike regular table buffers, temp tables reside on the tier on which the first record was inserted. For example, if a temp table is declared on the server, the first record is inserted on the client, and the rest of the records are inserted on the server, all access to that table from the server happens on the client. It’s best to populate a temp table on the server because the data you need is probably coming from the database; still, you must be careful when your intent is to iterate over the data to populate a form. The easiest way to achieve this efficiently is to populate the temp table on the server, serialize the entire table down to a container, and then read all the records from the container back into a temp table on the client.

Removing Client Callbacks

Client callbacks occur when the client places a call to a server-bound method, and then the server places a call to a client-bound method. These calls can happen for two reasons. First, they occur when the client doesn’t send enough information to the server during its call, or sends the server a client object that encapsulates the information. Second, client callbacks occur when the server is either updating or accessing a form.

To remove the first kind of call, ensure that you send all the information the server needs in a serializable format, such as a packed container, record buffers, or value types (e.g., int, str, real, boolean). When the server accesses these types, it doesn’t need to go back to the client, as it does if you use an object type.

To remove the form’s logic, just send any necessary information about the form into the method, and manipulate the form only when the call returns instead of directly from inside the server. One of the best ways to defer operations on the client is with pack and unpack. By utilizing pack and unpack, you can serialize a class down to a container and then deserialize it on the other side.

Chunking Calls

To ensure the minimum number of round-trips between the client and the server, chunk them into one, static server method and pass in all the state needed to perform the operation.

One static server method you can use is NumberSeq::getNextNumForRefParmId. This method call is a static server call that contains the following line of code.

return NumberSeq::newGetNum(CompanyInfo::numRefParmId()).num();


Had this code run on the client, it would have caused four remote procedure call (RPC) round-trips (one for newGetNum, one for numRefParmId, one for num, and one to clean up the NumberSeq object that was created). By using a static server method, you can complete this operation in one RPC round-trip.

Another common example of chunking occurs when the client is doing Transaction Tracking System (TTS) operations. Frequently, a developer writes code similar to the following.

     Ttsbegin;
Record.update();
TTSCommit


You can save two round-trips if you chunk this code into one static server call. All TTS operations are initiated only on the server. To take advantage of this fact, do not invoke the ttsbegin and ttscommit call from the client to start the database transaction when the ttslevel is 0.

 
Others
 
- 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
- Sharepoint 2010 : Data Access Overview - Content Types (part 2) - Content Type Metadata
 
 
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