Preserve data when AIF service call fails

Dynamics AX AIF is great for all kind of interfaces and integration with 3rd party applications. By default AIF has an built-in transaction mechanism that prevents your system to become inconsistent if something goes wrong during processing.

Here is an example of a simple method which writes message data and the current transaction level into a table

[SysEntryPointAttribute]
public void call(Description _message)
{
    ERPServiceTable serviceTable;

    serviceTable.Message = _message;
    serviceTable.Info = strFmt("%1", appl.ttsLevel());
    serviceTable.insert();
}

Here is the service call from a C# console application

var client = new ERPService.ERPServiceClient();
client.ClientCredentials.Windows.ClientCredential.Domain = "YOUR_DOMAIN";
client.ClientCredentials.Windows.ClientCredential.UserName = "YOUR_USER";
client.ClientCredentials.Windows.ClientCredential.Password = "YOUR_PASSWORD";

var context = new ERPService.CallContext();
context.MessageId = Guid.NewGuid().ToString();
client.call(context, "Service Call");

When you call the service the result looks like this: Notice, the transaction level is already 1 although there is no ttsbegin in code.

AIF service call

But what happens when something goes wrong during processing the service call (e.g. posting a journal fails). Here is as simple method which can be used to simulate such a situation:

[SysEntryPointAttribute]
public void callWithError(Description _message,boolean _error)
{
    this.call(_message);
    if(_error)
    {
        throw error("Exception!");
    }
}

When you call the service method with the error flag set to FALSE, the message is written to the table and stays there.

context.MessageId = Guid.NewGuid().ToString();
client.callWithError(context, "Service Call without error", false);

However if you call the method with the error flag set to TRUE a rollback is triggered and your data is gone!

try
{
        context.MessageId = Guid.NewGuid().ToString();
        client.callWithError(context, "Service Call 2 with error", true);
}
catch
{
        Console.WriteLine("The service failed as expected!");
}

The table contains only 2 entries for both successful service calls. The data from the third service call is gone.

Service call with error not saved

However, if you want to keep the initial data for a post mortem analysis, this behavior is a problem. One way to work around this rollback is to reduce the transaction level back to 0 by calling an additional ttscommit. This will ensure no rollback will delete the transmitted data. Finally, raise the ttslevel back to 1 for further processing.

[SysEntryPointAttribute]
public void callWithError(Description _message,boolean _error = false)
{
    this.call(_message);

    ttsCommit;
    ttsBegin;

   
    if(_error)
    {
        throw error("Exception!");
    }
}

When you call the service method with the error flag set to true, the method still fails. But the initial transmitted data is preserved and can be used for analysis or manual processing.

Service call with error preserverd

BTW.

A more relaxed way to address this issue is to separate interfaces from business logic. For example provide two methods, one to transmit the data and another to process the data after it was successfully transmitted. If a second method is not an option (for what reason ever) write a batch class which processes the data. However, if you require immediate processing and a second call is not feasible this workaround may help.

Advertisements

Über erpcoder
Software Engineer and Dynamics AX enthusiast working in Research & Development for InsideAx

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: