Skip to content

Latest commit

 

History

History
50 lines (38 loc) · 3.76 KB

PX1046.md

File metadata and controls

50 lines (38 loc) · 3.76 KB

PX1046

This document describes the PX1046 diagnostic.

Summary

Code Short Description Type Code Fix
PX1046 Long-running operations cannot be started within event handlers. Error Unavailable

Diagnostic Description

Long-running operations cannot be started within event handlers.

To fix the issue, you remove the invocation of the long-running operation and rework the related business logic. You can consider to configure business events related to data changes or monitored on a schedule in Acumatica ERP and perform the long-running operation once a notification about one of these events is received from Acumatica ERP. For detais about business events, see Business Events Related to Data Changes, Business Events Monitored on a Schedule.

Example of Incorrect Code

public class BinExtension : PXGraphExtension<INSiteMaint>
{
    public void INLocation_RowPersisted(PXCache sender, PXRowPersistedEventArgs e)
    {
        if (e.TranStatus != PXTranStatus.Completed) return;

        try
        {
            PXLongOperation.StartOperation(this, delegate () // The PX1046 error is displayed for this line.
            {
                //export records
            });
        }
        catch (Exception ex)
        {
            PXTrace.WriteError($"INLocation_RowPersisted - Failed. {ex}");
        }
    }
}

In the code above, a frequent scenario of using a long-running operation is shown. In the RowPersisted event handler, the long-running operation is initiated when the status of the transaction is set to Completed.

The long-running operation usually performs synchronization with an external system. The goal of the status check is to prevent the start of the synchronization before the database transaction is commited to the database. If the synchronization starts before the commit of the database transaction is finished then a data inconsistency will appear between Acumatica ERP and the external service in case the database transaction fails and is rollbacked. However, the check in the example only applies to a transaction scope created inside the graph's Persist method. Acumatica Framework transaction scope commits a database transaction to the database only at the end of a topmost scope. If there is an outer transaction scope for the graph in the code above, for example, when the graph is created by some other processing graph, then the actual database transaction is commited to the database only when the outer transaction scope is completed. But the long-running operation will still start and a data consistency will appear between Acumatica ERP and the external system.

You cannot reliably add to the graph a piece of business logic which is executed only after all changes are successfully persisted to the database and which introduces changes which cannot be reverted with the database transaction rollback. You need to use business events mentioned earlier.

Related Articles