web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

No record found.

News and Announcements icon
Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Suggested Answer

Issue with order transaction records are being written

(0) ShareShare
ReportReport
Posted on by

Hello,

Sorry, I am relatively new to X++, so apologize for asking what might have a simple solution.

We have custom code to update custom tables with a parent/child relationship when a sales order is confirmed. The code uses ttsbegin/ttscommit for inserting new records.

The issue we have is when the transaction is complete, it writes a child record before it writes the parent record, in general, not an issue, except we are also using dual write to a CE environment and the child table has a lookup to the parent table in CE. Since the parent record isn't written first, we are getting an error in dual write on the lookup in CE.

Is there a way to make sure that the parent record is written first?

I have the same question (0)
  • Suggested answer
    nmaenpaa Profile Picture
    101,166 Moderator on at

    Hi Elonna,

    if I understand correctly, you are saying that your custom code writes the child record before the parent record. And you would like it to be the other way around. To me it seems that you need to adjust your code so that the parent record is written first. Usually if you implement the table relations correctly, the system should prevent an orphan child record from being created.

    Perhaps you could share your code to help us understand your scenario better? Also any other additional information is welcome.

  • Elonna Profile Picture
    on at

    Thank you for your response. It is not writing any of the records to the table until the transaction is complete. We had the process in debug, and when it does the insert for the parent record, it is not in the parent table. It inserts all of the child records first, before actually writing to the tables, but it seems as if it is writing the child records first since dual write sync happens as the records are being written.

    Here is the code:

    [ExtensionOf(tableStr(CustConfirmTrans))]
    final class MazCustConfirmTransTable_Extension
    {
       
        /// 
        /// mca Srikrishna sallam  12-2-2021 - 12096 Sync Asset Tables COC for Insert method
        /// 
        public void insert()
        {
            next insert();
            this.SyncAssetandAssetAccesoriesTable();
        }
    
        public void update()
        {
            next update();
            this.SyncAssetandAssetAccesoriesTable();
        }
    
        public void SyncAssetandAssetAccesoriesTable()
        {
            SalesTable                  salesTable;
            SalesLine                   salesLine;
            InventTrans                 inventTrans;
            InventDim                   inventDim;
            InventTable                 inventTable;
            EcoResProduct               ecoResProduct;        
            EcoResProducttranslation    ecoResProducttranslation;
            InventTransOrigin           inventTransOrigin;
            MazSOTableAttributes        mazSOTableAttributes;
            MazInventTableAttributes    mazInventTableAttributes;
            SalesTotals                 salesTotals;
            MazCommissionAmount         mazSumCommissionAmounts;
    
    
            select firstonly salesTable where salesTable.SalesId == this.SalesId
                join mazSOTableAttributes where mazSOTableAttributes.SalesId == salesTable.SalesId;
    
            if(salesTable.RecId)
            {
                select firstonly inventTable where inventTable.ItemId == this.ItemId
                    join    mazInventTableAttributes where mazInventTableAttributes.ItemId == inventTable.ItemId
                    join    ecoResProduct where ecoResProduct.DisplayProductNumber == mazInventTableAttributes.ItemId
                    join    ecoResProductTranslation where ecoResProductTranslation.Product == ecoResProduct.Recid;
    
    
                select firstonly inventTransOrigin
                    where inventTransOrigin.InventTransId  == this.InventTransId
                    join inventTrans where inventTrans.inventTransOrigin == inventTransorigin.RecId
                    join inventDim where inventDim.inventDimId == inventTrans.inventDimId;
    
                
                //no check needed for serial number as this is sales order shipping status and by now we will have the Serial Number
                if(mazSOTableAttributes.RecId)
                {
                    MazAssetMasterTable mazAssetMasterTable;
                    switch(mazInventTableAttributes.MazItemType)
                    {
                        case MazItemType::Machine :
                          
                            /// check Asset record exists, if record exists update it not create.
                            if(inventDim.RecId &&
                                inventDim.inventSerialId &&
                                inventTrans.StatusIssue == StatusIssue::ReservPhysical)
                            {
                                ttsbegin;
                                select firstonly forupdate  RecId, CustAccount , mazSerialNum
                                    from                    mazAssetMasterTable
                                    where                   mazAssetMasterTable.MazSerialNum == inventDim.inventSerialId
                                    &&                      mazAssetMasterTable.CustAccount == salesTable.CustAccount;
    
                                if(mazAssetMasterTable.RecId &&
                                    mazAssetMasterTable.CustAccount &&
                                    mazAssetMasterTable.mazSerialNum)
                                {
                                   
                                    //mazAssetMasterTable.InItFromMazInventTableAttributes(mazInventTableAttributes, salesTable, inventDim);
                                    mazAssetMasterTable.InItFromMazSOTableAttributes(mazSOTableAttributes, salesTable, inventDim);
    
                                    // MCA Connect - Justin Tibbetts - 02/17/2022 - Mazak_12096_CEAssetTableIntegration
                                    mazAssetMasterTable.MazSalesPoolId = salesTable.SalesPoolId;
                                    mazAssetMasterTable.MazModelCode = mazSOTableAttributes.ModelCode;
    
                                    salesTotals = SalesTotals::construct(salesTable);
    
                                    mazSumCommissionAmounts = salesTable.MazCommissionAmount1   salesTable.MazCommissionAmount2   
                                        salesTable.MazCommissionAmount3;
    
                                    mazAssetMasterTable.MazSalesAmtLessDistComm = salesTotals.totalBalance() - mazSumCommissionAmounts;
                                    
                                    if (salesTable.ShippingDateConfirmed == dateNull())
                                    {
                                        mazAssetMasterTable.MazEstimatedShipDate = salesTable.ShippingDateRequested;
                                    }
                                    else
                                    {
                                        mazAssetMasterTable.MazEstimatedShipDate = salesTable.ShippingDateConfirmed;
                                    }
                                    // MCA Connect - Justin Tibbetts - 02/17/2022 - Mazak_12096_CEAssetTableIntegration
    
                                    mazAssetMasterTable.MazProductNumber = this.itemId;
                                    mazAssetMasterTable.MazProductDescription = ecoResProducttranslation.Name;
    
                                    if(mazAssetMasterTable.ValidateWrite())
                                    {
                                        mazAssetMasterTable.update();
                                    }
                                }
                                else
                                {
                                    mazAssetMasterTable.InItFromMazSOTableAttributes(mazSOTableAttributes, salesTable, inventDim);
    
                                    // MCA Connect - Justin Tibbetts - 02/17/2022 - Mazak_12096_CEAssetTableIntegration
                                    mazAssetMasterTable.MazSalesPoolId = salesTable.SalesPoolId;
                                    mazAssetMasterTable.MazModelCode = mazSOTableAttributes.ModelCode;
    
                                    salesTotals = SalesTotals::construct(salesTable);
    
                                    mazSumCommissionAmounts = salesTable.MazCommissionAmount1   salesTable.MazCommissionAmount2  
                                        salesTable.MazCommissionAmount3;
    
                                    mazAssetMasterTable.MazSalesAmtLessDistComm = salesTotals.totalBalance() - mazSumCommissionAmounts;
    
                                    if (salesTable.ShippingDateConfirmed == dateNull())
                                    {
                                        mazAssetMasterTable.MazEstimatedShipDate = salesTable.ShippingDateRequested;
                                    }
                                    else
                                    {
                                        mazAssetMasterTable.MazEstimatedShipDate = salesTable.ShippingDateConfirmed;
                                    }
                                    // MCA Connect - Justin Tibbetts - 02/17/2022 - Mazak_12096_CEAssetTableIntegration
    
                                    mazAssetMasterTable.MazProductNumber = this.itemId;
                                    mazAssetMasterTable.MazProductDescription = ecoResProducttranslation.Name;
                                    mazAssetMasterTable.insert();
                                }
                                ttscommit;
                            }
                            break;
    
                        case MazItemType::Other :
    
                            MazAssetAccessoryTable mazAssetAccessoryTable;
    
                            SalesTable                  salesTable1;
                            SalesLine                   salesLine1;
                            InventTrans                 inventTrans1;
                            InventDim                   inventDim1;
                            InventTransOrigin           inventTransOrigin1;
                            MazInventTableAttributes    mazInventTableAttributes1;
    
                            ttsbegin;
                            /// check Asset accessory record exists, if record exists update it not create.                        
                            select firstonly    salesline1
                                    where           salesline1.SalesId == this.SalesId
                                    join            mazInventTableAttributes1
                                    where           mazInventTableAttributes1.itemId == salesline1.itemId
                                    &&              mazInventTableAttributes1.MazItemType == MazItemType::Machine
                                    join            inventTransOrigin1
                                    where           inventTransOrigin1.InventTransId  == salesLine1.InventTransId
                                    join            inventTrans1
                                    where           inventTrans1.inventTransOrigin == inventTransorigin1.RecId
                                    join            inventDim1
                                    where           inventDim1.inventDimId == inventTrans1.inventDimId;
                            
    
                            // add the exists or find method to the table move this query there
                            select firstonly forupdate  RecId
                                from                    mazAssetAccessoryTable
                                where                   mazAssetAccessoryTable.MazSerialNum == inventDim1.inventSerialId
                                &&                      mazAssetAccessoryTable.MazPartNumber ==  this.ItemId;
    
    
    
                            if(mazAssetAccessoryTable.RecId && inventDim1.inventSerialId)
                            {
                               
                                mazAssetAccessoryTable.InItFromInventTables(inventDim1, inventTable);
                                mazAssetAccessoryTable.MazName = ecoResProducttranslation.Name;
                                mazAssetAccessoryTable.SalesId = this.SalesId;
                                if(mazAssetAccessoryTable.ValidateWrite())
                                {
                                    mazAssetAccessoryTable.update();
                                }
                              
                            }
                            else if(inventDim1.inventSerialId)
                            {
                                mazAssetAccessoryTable.InItFromInventTables( inventDim1 , inventTable);
                                mazAssetAccessoryTable.MazName = ecoResProducttranslation.Name;
                                mazAssetAccessoryTable.SalesId = this.SalesId;
                                mazAssetAccessoryTable.insert();
                            }
                            ttscommit;
    
                            break;
                    }
                }
    
            }
        }
    
    }

  • Suggested answer
    nmaenpaa Profile Picture
    101,166 Moderator on at

    Hi,

    actually the record is written to the database during insert/update, but others can't see it before the transaction is committed.

    And once the transaction is committed, everything that happened in the transaction should be visible at the same time. If only part of the changes in that transaction would be effective, that would cause serious issues across the system all the time.

    You might have misinterpreted the situation.

    Having said that, you could try wrapping the next() call and your sync call to the same transaction and see if it helps in your situation.

  • Elonna Profile Picture
    on at

    I am sure I'm misinterpreting it :)

    My thoughts were based on the fact that in dual write, a child record was being synced first, not the parent record. My understanding of dual write is that when the record is written to the table it is also synced to dual write, so it seemed as if the child record was being written to the table before the parent record.

    I will try your suggestion. Thank you.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Stars!

Meet the Microsoft Dynamics 365 Contact Center Champions

We are thrilled to have these Champions in our Community!

Congratulations to the March Top 10 Community Leaders

These are the community rock stars!

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Giorgio Bonacorsi Profile Picture

Giorgio Bonacorsi 657

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 453 Super User 2026 Season 1

#3
Martin Dráb Profile Picture

Martin Dráb 190 Most Valuable Professional

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans