Update conflict error in table SalesParmUpdate while posting an invoice for sales order.

I have a requirement to avoid update conflict error in table SalesParmUpdate. I found that in the form SalesEditLines data source SalesParmUpdate there is Super() call that updates the records in SalesParmUpdate table. I believe as the table has OCC enabled as true hence there is recversion conflict happening while the user try to update the table SalesParmUpdate.
What I want to do is check for the recversion before the Super() call is made so just wanted some help as to whether can we find what exactly fields are having different value then the one saved in database other than the RecVersion. Any help in this direction will be great.
Thanks in advance.

Update conflict will happen, when you are trying to update the old version of the record. Usually happens when multiple people modifying the same record same time.
Why it is happening in your case? Any customization’s in that area?

No Kranthi there is no code modification but it seems sometimes the client gets this error in live environment while posting a packing slip or invoice for serialized items in sales orders. Its not a consistent issue but reported by them many times. Seems some back ground AIF integration might be cause of updating the table. But not very sure.

You may have to identify the root of the issue or identify the code that is resulting the update conflict in order to fix it.

I went through some links and found out that in past when some people have face such update conflict error issues they have reread the database to resolve it but in my case even that won’t be possible because it will overwrite user made changes. I need to figure out some way to check what all fields have been modified by the user and get user made changes once the datasource is reread to get the recversion that exists in database.

You should not be merging the changes done by the multiple processes at a time. Two or more processes cannot update a record at same time, the error mean it. Not sure why (the requirement) the same record is updated from external sources(AIF) when another process is allowed to post or updated related record. I feel there is a process gap, which needs to be identified.

Thanks Kranthi for input. we are trying to identify the exact situation leading to this update of SalesParmTable before posting gets done. Once that gets figured than only a solution will be able to deviced. I will update this thread with my findings so that if anyone has any solution it can be applied to the form SalesEditLines or the process that is creating such issues.

HI guys, i got deadlock error while posting sales invoice from other application using AX web service, below is my code to post sales invoice:

[
SysEntryPointAttribute(true),
AifCollectionTypeAttribute(“return”,Types::String, “Notes”)
]

public Notes PostSalesInvoice(SalesId _subJobNo, InvoiceId _invoiceNo)
{
AxSalesParmTable axSalesParmTable;
AxSalesParmLine axSalesParmLine;
SalesParmTable salesParmTable;
SalesParmLine salesParmLine;
SalesTable salesTable = SalesTable::find(_subJobNo);
SalesLine _salesLine;
SalesLine salesLine;
WLKSalesTableStageTable wlkSalesStageTable;
WLKSalesLineStageTable wlkSalesLineStageTable;
CreatedTransactionId createdTransactionId;
SalesFormLetter_Invoice salesFormLetter_Invoice;
SalesParmUpdate salesParmUpdate;
int ttsBeginCommitFound;
AIFInfoLog aifInfoLog = new AIFInfoLog();
InfologData msg;
int i;

Notes ret = “Failed”;
#OCCRetryCount

ttsBeginCommitFound = appl.ttsLevel();

while (appl.ttsLevel() > 0)
{
ttsCommit;

}
try
{
ttsBegin;

salesFormLetter_Invoice = SalesFormLetter::construct(DocumentStatus::Invoice);

salesFormLetter_Invoice = salesFormLetter_Invoice::newInvoice();

salesFormLetter_Invoice.initParameters(salesParmUpdate, Printout::Current, NoYes::No, NoYes::No, NoYes::No, NoYes::No);

salesFormLetter_Invoice.createParmUpdateFromParmUpdateRecord(
SalesFormletterParmData::initSalesParmUpdateFormletter(DocumentStatus::Invoice,salesFormLetter_Invoice.pack()));

salesParmUpdate = salesFormLetter_Invoice.salesParmUpdate();
salesParmUpdate.DocumentStatus = DocumentStatus::Invoice;
salesParmUpdate.SpecQty = SalesUpdate::All;
salesParmUpdate.Proforma = NoYes::No;
salesParmUpdate.ReduceOnHand = NoYes::No;
salesParmUpdate.CheckCreditMax = TypeOfCreditmaxCheck::BalanceAll;
salesParmUpdate.Storno = NoYes::No;
salesParmUpdate.CreditRemaining = NoYes::Yes;
salesParmUpdate.SumBy = AccountOrder::None;

salesFormLetter_Invoice.salesParmUpdate(salesParmUpdate);
salesFormLetter_Invoice.reArrangeNow(false);

axSalesParmTable = AxSalesParmTable::construct();
axSalesParmTable.parmParmId(salesFormLetter_Invoice.parmId());
axSalesParmTable.parmSalesId(salesTable.SalesId);
axSalesParmTable.parmCITInvoiceId(_invoiceNo);
axSalesParmTable.parmInvoiceAccount(wlkSalesStageTable.CustomerCode);
axSalesParmTable.parmOrdering(DocumentStatus::Invoice);
axSalesParmTable.parmTransdate(today());
axSalesParmTable.parmDocumentDate(today());
axSalesParmTable.defaulting(true);
axSalesParmTable.save();

select firstOnly createdTransactionId
from wlkSalesLineStageTable order by CreatedTransactionId desc
where wlkSalesLineStageTable.SubJobNo == _subJobNo
&& wlkSalesLineStageTable.InvoiceNo == _invoiceNo
&& wlkSalesLineStageTable.Type == WLKSalesStageTableType::Invoice
&& wlkSalesLineStageTable.Status == WLKIntegrationStatus::Success;

createdTransactionId = wlkSalesLineStageTable.createdTransactionId;

while select wlkSalesLineStageTable
where wlkSalesLineStageTable.SubJobNo == _subJobNo
&& wlkSalesLineStageTable.InvoiceNo == _invoiceNo
&& wlkSalesLineStageTable.Type == WLKSalesStageTableType::Invoice
&& wlkSalesLineStageTable.Status == WLKIntegrationStatus::Success
&& wlkSalesLineStageTable.createdTransactionId == createdTransactionId
{
select salesLine
where salesLine.ItemId == wlkSalesLineStageTable.ChargeCode
&& salesLine.SalesId == wlkSalesLineStageTable.SubJobNo
&& salesLine.TaxItemGroup == wlkSalesLineStageTable.ChargeSalesTaxCode
&& salesLine.SalesStatus != SalesStatus::Invoiced
&& salesLine.SalesStatus != SalesStatus::Canceled;

if(salesLine)
{
axSalesParmLine= AxSalesParmLine::construct();
axSalesParmLine.parmParmId(axSalesParmTable.parmParmId());
axSalesParmLine.parmTableRefId(axSalesParmTable.parmTableRefId());
axSalesParmLine.parmItemId(wlkSalesLineStageTable.ChargeCode);
//axSalesParmLine.parmRemainBeforeInvent(salesLine.RemainInventPhysical);
axSalesParmLine.parmDeliverNow(wlkSalesLineStageTable.Quantity);
axSalesParmLine.parmInventTransId(salesLine.InventTransId);
axSalesParmLine.parmInventDimId(salesLine.InventDimId);
axSalesParmLine.parmSalesLineRecId(salesLine.RecId);
axSalesParmLine.parmInvoiceAccount(wlkSalesStageTable.CustomerCode); //CETAS
axSalesParmLine.salesFormLetter(salesFormLetter_Invoice);
axSalesParmLine.save();
}
}
salesFormLetter_Invoice.run();

ret = “Success”;

ttsCommit;
}
catch(Exception::Error)
{
ttsBegin;

i=1;

while(i<infologline())
{
ret+=infolog.text(i);
i++;
}
ret +=aifInfoLog.getLastErrorMessage();
ttsCommit;
}
catch (Exception::Deadlock)
{
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::Deadlock;
}
else
{
retry;
}
}
catch (Exception::UpdateConflict)
{
// try to resolve update conflict
if (appl.ttsLevel() == 0)
{
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::UpdateConflictNotRecovered;
}
else
{
retry;
}
}
else
{
throw Exception::UpdateConflict;
}
}
catch(Exception::DuplicateKeyException)
{
// retry in case of an duplicate key conflict
if (appl.ttsLevel() == 0)
{
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::DuplicateKeyExceptionNotRecovered;
}
else
{
retry;
}
}
else
{
throw Exception::DuplicateKeyException;
}
}

while(ttsBeginCommitFound > 0)
{
ttsBeginCommitFound --;
ttsBegin;
}

return ret;
}