Roger Blanchard
413 posts
Registered:
29 Jun 2018
08 Dec 2019
in reply to
Mike Fechner
Link to this post
Its all server-side code. We are creating TT records from parsing our electronic journal and then we call the PerformDBUpdate in each class that will use the dataset model classes to update the DB.
Yes, we have many clients sending requests to PASOE. We will have many POS devices in a store all sending POS transactions. I am sure it is a deadly embrace where each request is waiting on the other. After the lock wait timeout expires one request will throw the error and the other will finish just fine.
As a test, I changed the code to use pessimistic locking and the issue goes away.
FOR FIRST eGeneralTotal ON ERROR UNDO, THROW:
// UPDATE CASHIER TOTALS FIRST
poGeneralTotal:NewFilter(oTransactionTotals:PostingDate, // SaleDate
"D", // Period
oTransactionTotals:CashierNum, // CashierNum
"" // RegNum
).
poGeneralTotal:TrackingChanges = TRUE. // enable TrackingChanges
IF NOT poGeneralTotal:GeneralTotal:Available THEN // create if does not exist
DO:
poGeneralTotal:GeneralTotal:Create().
poGeneralTotal:GeneralTotal:SaleDate = oTransactionTotals:PostingDate.
poGeneralTotal:GeneralTotal:Period = "D".
poGeneralTotal:GeneralTotal:CashierNum = oTransactionTotals:CashierNum.
poGeneralTotal:GeneralTotal:RegNum = "".
END.
/* Roger Blanchard / Osprey Retail Systems Apr 3, 2019
Now update existing fields with values from TT
*/
ASSIGN
/* let's save current values so we can pass to RulesEngine */
iNumNoSales = poGeneralTotal:GeneralTotal:NumNoSales
iNumCancels = poGeneralTotal:GeneralTotal:NumCancels
iNumPrevCancels = poGeneralTotal:GeneralTotal:NumPrevCancels
iNumCusts = poGeneralTotal:GeneralTotal:NumCusts
poGeneralTotal:GeneralTotal:NumCusts = poGeneralTotal:GeneralTotal:NumCusts + eGeneralTotal.NumCusts
poGeneralTotal:GeneralTotal:NumCustRtn = poGeneralTotal:GeneralTotal:NumCustRtn + eGeneralTotal.NumCustRtn
poGeneralTotal:GeneralTotal:NumItemSold = poGeneralTotal:GeneralTotal:NumItemSold + eGeneralTotal.NumItemSold
poGeneralTotal:GeneralTotal:NumNoSales = poGeneralTotal:GeneralTotal:NumNoSales + eGeneralTotal.NumNoSales
poGeneralTotal:GeneralTotal:GrossSales = poGeneralTotal:GeneralTotal:GrossSales + eGeneralTotal.GrossSales
poGeneralTotal:GeneralTotal:ARChange = poGeneralTotal:GeneralTotal:ARChange + eGeneralTotal.ARChange
poGeneralTotal:GeneralTotal:Grandtotal = poGeneralTotal:GeneralTotal:Grandtotal + eGeneralTotal.Grandtotal
poGeneralTotal:GeneralTotal:NonAddSales = poGeneralTotal:GeneralTotal:NonAddSales + eGeneralTotal.NonAddSales
poGeneralTotal:GeneralTotal:NumCancels = poGeneralTotal:GeneralTotal:NumCancels + eGeneralTotal.NumCancels
poGeneralTotal:GeneralTotal:CancelSaleAmt = poGeneralTotal:GeneralTotal:CancelSaleAmt + eGeneralTotal.CancelSaleAmt
poGeneralTotal:GeneralTotal:NumItemEntry = poGeneralTotal:GeneralTotal:NumItemEntry + eGeneralTotal.NumItemEntry
poGeneralTotal:GeneralTotal:NonTaxableSale = poGeneralTotal:GeneralTotal:NonTaxableSale + eGeneralTotal.NonTaxableSale
poGeneralTotal:GeneralTotal:NumCreditTrans = poGeneralTotal:GeneralTotal:NumCreditTrans + eGeneralTotal.NumCreditTrans
poGeneralTotal:GeneralTotal:CreditTransAmt = poGeneralTotal:GeneralTotal:CreditTransAmt + eGeneralTotal.CreditTransAmt
poGeneralTotal:GeneralTotal:NumPrevCancels = poGeneralTotal:GeneralTotal:NumPrevCancels + eGeneralTotal.NumPrevCancels
poGeneralTotal:GeneralTotal:PrevCancelSaleAmt = poGeneralTotal:GeneralTotal:PrevCancelSaleAmt + eGeneralTotal.PrevCancelSaleAmt
poGeneralTotal:GeneralTotal:DonorCnt = poGeneralTotal:GeneralTotal:DonorCnt + eGeneralTotal.DonorCnt
poGeneralTotal:GeneralTotal:TrainingSaleCnt = poGeneralTotal:GeneralTotal:TrainingSaleCnt + eGeneralTotal.TrainingSaleCnt
poGeneralTotal:GeneralTotal:SuspendedSaleCnt = poGeneralTotal:GeneralTotal:SuspendedSaleCnt + eGeneralTotal.SuspendedSaleCnt
NO-ERROR.
poGeneralTotal:SaveChanges(). // save changes to the DB
/* Roger Blanchard / Osprey Retail Systems Apr 3, 2019
Call RuleEngine here. I am thinking turning RuleEngine into a service
and load in Servicex.xml
*/
// do we want to add a System Parameter to enable this? */
// RulesEngine:Instance:CheckGeneralTotal(BUFFER GeneralTotal, iNumNoSales, iNumCancels, iNumPrevCancels, iNumCusts).
/* now update monthly cashier totals */
poGeneralTotal:NewFilter(oTransactionTotals:MonthEnd,
"M",
oTransactionTotals:CashierNum,
""
).
poGeneralTotal:TrackingChanges = TRUE. // enable TrackingChanges
IF NOT poGeneralTotal:GeneralTotal:Available THEN // create record if it does not already exist
DO:
poGeneralTotal:GeneralTotal:Create().
poGeneralTotal:GeneralTotal:SaleDate = oTransactionTotals:MonthEnd.
poGeneralTotal:GeneralTotal:Period = "M".
poGeneralTotal:GeneralTotal:CashierNum = oTransactionTotals:CashierNum.
poGeneralTotal:GeneralTotal:RegNum = "".
END.
/* Roger Blanchard / Osprey Retail Systems Apr 3, 2019
Now update existing fields with values from TT
*/
ASSIGN
poGeneralTotal:GeneralTotal:NumCusts = poGeneralTotal:GeneralTotal:NumCusts + eGeneralTotal.NumCusts
poGeneralTotal:GeneralTotal:NumCustRtn = poGeneralTotal:GeneralTotal:NumCustRtn + eGeneralTotal.NumCustRtn
poGeneralTotal:GeneralTotal:NumItemSold = poGeneralTotal:GeneralTotal:NumItemSold + eGeneralTotal.NumItemSold
poGeneralTotal:GeneralTotal:NumNoSales = poGeneralTotal:GeneralTotal:NumNoSales + eGeneralTotal.NumNoSales
poGeneralTotal:GeneralTotal:GrossSales = poGeneralTotal:GeneralTotal:GrossSales + eGeneralTotal.GrossSales
poGeneralTotal:GeneralTotal:ARChange = poGeneralTotal:GeneralTotal:ARChange + eGeneralTotal.ARChange
poGeneralTotal:GeneralTotal:Grandtotal = poGeneralTotal:GeneralTotal:Grandtotal + eGeneralTotal.Grandtotal
poGeneralTotal:GeneralTotal:NonAddSales = poGeneralTotal:GeneralTotal:NonAddSales + eGeneralTotal.NonAddSales
poGeneralTotal:GeneralTotal:NumCancels = poGeneralTotal:GeneralTotal:NumCancels + eGeneralTotal.NumCancels
poGeneralTotal:GeneralTotal:CancelSaleAmt = poGeneralTotal:GeneralTotal:CancelSaleAmt + eGeneralTotal.CancelSaleAmt
poGeneralTotal:GeneralTotal:NumItemEntry = poGeneralTotal:GeneralTotal:NumItemEntry + eGeneralTotal.NumItemEntry
poGeneralTotal:GeneralTotal:NonTaxableSale = poGeneralTotal:GeneralTotal:NonTaxableSale + eGeneralTotal.NonTaxableSale
poGeneralTotal:GeneralTotal:NumCreditTrans = poGeneralTotal:GeneralTotal:NumCreditTrans + eGeneralTotal.NumCreditTrans
poGeneralTotal:GeneralTotal:CreditTransAmt = poGeneralTotal:GeneralTotal:CreditTransAmt + eGeneralTotal.CreditTransAmt
poGeneralTotal:GeneralTotal:NumPrevCancels = poGeneralTotal:GeneralTotal:NumPrevCancels + eGeneralTotal.NumPrevCancels
poGeneralTotal:GeneralTotal:PrevCancelSaleAmt = poGeneralTotal:GeneralTotal:PrevCancelSaleAmt + eGeneralTotal.PrevCancelSaleAmt
poGeneralTotal:GeneralTotal:DonorCnt = poGeneralTotal:GeneralTotal:DonorCnt + eGeneralTotal.DonorCnt
poGeneralTotal:GeneralTotal:TrainingSaleCnt = poGeneralTotal:GeneralTotal:TrainingSaleCnt + eGeneralTotal.TrainingSaleCnt
poGeneralTotal:GeneralTotal:SuspendedSaleCnt = poGeneralTotal:GeneralTotal:SuspendedSaleCnt + eGeneralTotal.SuspendedSaleCnt
NO-ERROR.
poGeneralTotal:SaveChanges(). // save changes to the DB
// NOW UPDATE REGISTER TOTALS
poGeneralTotal:NewFilter(oTransactionTotals:PostingDate,
"D",
0,
oTransactionTotals:RegNum
).
poGeneralTotal:TrackingChanges = TRUE. // enable TrackingChanges
IF NOT poGeneralTotal:GeneralTotal:Available THEN // create if does not exist
DO:
poGeneralTotal:GeneralTotal:Create().
poGeneralTotal:GeneralTotal:SaleDate = oTransactionTotals:PostingDate.
poGeneralTotal:GeneralTotal:Period = "D".
poGeneralTotal:GeneralTotal:CashierNum = 0.
poGeneralTotal:GeneralTotal:RegNum = oTransactionTotals:RegNum.
END.
/* Roger Blanchard / Osprey Retail Systems Apr 3, 2019
Now update existing fields with values from TT
*/
ASSIGN
poGeneralTotal:GeneralTotal:NumCusts = poGeneralTotal:GeneralTotal:NumCusts + eGeneralTotal.NumCusts
poGeneralTotal:GeneralTotal:NumCustRtn = poGeneralTotal:GeneralTotal:NumCustRtn + eGeneralTotal.NumCustRtn
poGeneralTotal:GeneralTotal:NumItemSold = poGeneralTotal:GeneralTotal:NumItemSold + eGeneralTotal.NumItemSold
poGeneralTotal:GeneralTotal:NumNoSales = poGeneralTotal:GeneralTotal:NumNoSales + eGeneralTotal.NumNoSales
poGeneralTotal:GeneralTotal:GrossSales = poGeneralTotal:GeneralTotal:GrossSales + eGeneralTotal.GrossSales
poGeneralTotal:GeneralTotal:ARChange = poGeneralTotal:GeneralTotal:ARChange + eGeneralTotal.ARChange
poGeneralTotal:GeneralTotal:Grandtotal = poGeneralTotal:GeneralTotal:Grandtotal + eGeneralTotal.Grandtotal
poGeneralTotal:GeneralTotal:NonAddSales = poGeneralTotal:GeneralTotal:NonAddSales + eGeneralTotal.NonAddSales
poGeneralTotal:GeneralTotal:NumCancels = poGeneralTotal:GeneralTotal:NumCancels + eGeneralTotal.NumCancels
poGeneralTotal:GeneralTotal:CancelSaleAmt = poGeneralTotal:GeneralTotal:CancelSaleAmt + eGeneralTotal.CancelSaleAmt
poGeneralTotal:GeneralTotal:NumItemEntry = poGeneralTotal:GeneralTotal:NumItemEntry + eGeneralTotal.NumItemEntry
poGeneralTotal:GeneralTotal:NonTaxableSale = poGeneralTotal:GeneralTotal:NonTaxableSale + eGeneralTotal.NonTaxableSale
poGeneralTotal:GeneralTotal:NumCreditTrans = poGeneralTotal:GeneralTotal:NumCreditTrans + eGeneralTotal.NumCreditTrans
poGeneralTotal:GeneralTotal:CreditTransAmt = poGeneralTotal:GeneralTotal:CreditTransAmt + eGeneralTotal.CreditTransAmt
poGeneralTotal:GeneralTotal:NumPrevCancels = poGeneralTotal:GeneralTotal:NumPrevCancels + eGeneralTotal.NumPrevCancels
poGeneralTotal:GeneralTotal:PrevCancelSaleAmt = poGeneralTotal:GeneralTotal:PrevCancelSaleAmt + eGeneralTotal.PrevCancelSaleAmt
poGeneralTotal:GeneralTotal:DonorCnt = poGeneralTotal:GeneralTotal:DonorCnt + eGeneralTotal.DonorCnt
poGeneralTotal:GeneralTotal:TrainingSaleCnt = poGeneralTotal:GeneralTotal:TrainingSaleCnt + eGeneralTotal.TrainingSaleCnt
poGeneralTotal:GeneralTotal:SuspendedSaleCnt = poGeneralTotal:GeneralTotal:SuspendedSaleCnt + eGeneralTotal.SuspendedSaleCnt
NO-ERROR.
poGeneralTotal:SaveChanges(). // save changes to the DB
/* now update monthly register totals */
poGeneralTotal:NewFilter(oTransactionTotals:MonthEnd,
"M",
0,
oTransactionTotals:RegNum
).
poGeneralTotal:TrackingChanges = TRUE. // enable TrackingChanges
IF NOT poGeneralTotal:GeneralTotal:Available THEN // create record if it does not already exist
DO:
poGeneralTotal:GeneralTotal:Create().
poGeneralTotal:GeneralTotal:SaleDate = oTransactionTotals:MonthEnd.
poGeneralTotal:GeneralTotal:Period = "M".
poGeneralTotal:GeneralTotal:CashierNum = 0.
poGeneralTotal:GeneralTotal:RegNum = oTransactionTotals:RegNum.
END.
/* Roger Blanchard / Osprey Retail Systems Apr 3, 2019
Now update existing fields with values from TT
*/
ASSIGN
poGeneralTotal:GeneralTotal:NumCusts = poGeneralTotal:GeneralTotal:NumCusts + eGeneralTotal.NumCusts
poGeneralTotal:GeneralTotal:NumCustRtn = poGeneralTotal:GeneralTotal:NumCustRtn + eGeneralTotal.NumCustRtn
poGeneralTotal:GeneralTotal:NumItemSold = poGeneralTotal:GeneralTotal:NumItemSold + eGeneralTotal.NumItemSold
poGeneralTotal:GeneralTotal:NumNoSales = poGeneralTotal:GeneralTotal:NumNoSales + eGeneralTotal.NumNoSales
poGeneralTotal:GeneralTotal:GrossSales = poGeneralTotal:GeneralTotal:GrossSales + eGeneralTotal.GrossSales
poGeneralTotal:GeneralTotal:ARChange = poGeneralTotal:GeneralTotal:ARChange + eGeneralTotal.ARChange
poGeneralTotal:GeneralTotal:Grandtotal = poGeneralTotal:GeneralTotal:Grandtotal + eGeneralTotal.Grandtotal
poGeneralTotal:GeneralTotal:NonAddSales = poGeneralTotal:GeneralTotal:NonAddSales + eGeneralTotal.NonAddSales
poGeneralTotal:GeneralTotal:NumCancels = poGeneralTotal:GeneralTotal:NumCancels + eGeneralTotal.NumCancels
poGeneralTotal:GeneralTotal:CancelSaleAmt = poGeneralTotal:GeneralTotal:CancelSaleAmt + eGeneralTotal.CancelSaleAmt
poGeneralTotal:GeneralTotal:NumItemEntry = poGeneralTotal:GeneralTotal:NumItemEntry + eGeneralTotal.NumItemEntry
poGeneralTotal:GeneralTotal:NonTaxableSale = poGeneralTotal:GeneralTotal:NonTaxableSale + eGeneralTotal.NonTaxableSale
poGeneralTotal:GeneralTotal:NumCreditTrans = poGeneralTotal:GeneralTotal:NumCreditTrans + eGeneralTotal.NumCreditTrans
poGeneralTotal:GeneralTotal:CreditTransAmt = poGeneralTotal:GeneralTotal:CreditTransAmt + eGeneralTotal.CreditTransAmt
poGeneralTotal:GeneralTotal:NumPrevCancels = poGeneralTotal:GeneralTotal:NumPrevCancels + eGeneralTotal.NumPrevCancels
poGeneralTotal:GeneralTotal:PrevCancelSaleAmt = poGeneralTotal:GeneralTotal:PrevCancelSaleAmt + eGeneralTotal.PrevCancelSaleAmt
poGeneralTotal:GeneralTotal:DonorCnt = poGeneralTotal:GeneralTotal:DonorCnt + eGeneralTotal.DonorCnt
poGeneralTotal:GeneralTotal:TrainingSaleCnt = poGeneralTotal:GeneralTotal:TrainingSaleCnt + eGeneralTotal.TrainingSaleCnt
poGeneralTotal:GeneralTotal:SuspendedSaleCnt = poGeneralTotal:GeneralTotal:SuspendedSaleCnt + eGeneralTotal.SuspendedSaleCnt
NO-ERROR.
poGeneralTotal:SaveChanges(). // save changes to the DB
THIS-OBJECT:UpdateZipCodeTotal(poGeneralTotal). // UPDATE our ZipCodeTotal table as well
THIS-OBJECT:UpdateProductivityTotal(poGeneralTotal). // update our Productivitytotal table as well
THIS-OBJECT:UpdateActiveCashier(poGeneralTotal). // update ActiveCashier record
THIS-OBJECT:UpdateCashierReconcil(poGeneralTotal). // update CashierReconcil reocrd
/* Roger Blanchard / Osprey Retail Systems Apr 3, 2019
Log any error here and then throw to caller
*/
CATCH e AS Progress.Lang.Error:
LogManagerWrapper:WriteError(e).
UNDO, THROW e.
END CATCH.
END.