How to Prevent Deadlock by Setting Record Reservation on Copied P42101 Custom Application
Purpose of Document
Disclaimer: Oracle will not be responsible for the changes made to standard programs due to this implementation and Oracle will not maintain any of these custom changes or be responsible for any problems arising from these changes.
The primary purpose of this document is to explain standard routine on how P42101 reserve records. But this document is not meant for guiding how to customize it.
Refer to <Document:1213383.1> - E1: 42: P42101 and P43070 Cause Deadlock in Competing to Update a Held Orders (F4209) Table. It explains the deadlock situation when two different processes try to update a same table (in this example, F4209 - Order Held File) when this table is blocked in Transaction Processing boundary (that is, from update table to COMMIT TRANSACTION.)
To overcome this deadlock issue, you need to implement Record Reservation routine. For further detail, refer to <Document:1142464.1> - E1: FDA: F00095 Record/Object Reservation in EnterpriseOne Interactive Application. As we can see here, through this configuration we can minimize possible deadlock and minimize dirty read or phantom read because data are to be updated by only one process.
Currently, the based on application P42101 (Sales Order Entry), is a typical MVC (Model, Controller and View) model application. For this reason you are not able to implement Record Reservation from the application level. You will need to make customizations to JDE standard objects. Note that Oracle will not be responsible for the changes made to standard programs due to this implementation and Oracle will not maintain any of these custom changes or be responsible for any problems arising from these changes. Also refer to <Document:1212163.1> - E1: 42: MVC Architecture (Powerform) and Sales Order Entry (P42101) for more information on MVC architecture.
How to implement Record Reservation in copied custom application?
To reserve transaction, add 'P42101' in UDC 00/RR - Record Reservation
Analyze As-Is code
A. Reservation
Business Function: B4210010 - CreateSalesOrderFunctions (Create Sales Order Functions)
Internal Function: IB4210010_ReserveRecord
Purpose: This function determines if Record Reservation is Active and attempts to reserve the order
*** Break In Code *** static void IB4210010_ReserveRecord(LPBHVRCOM lpBhvrCom, LPVOID lpVoid, LPDSSALESORDERHEADER lpdsSalesOrderHeader) { *** Break In Code *** jdeStrcpy((JCHAR*)dsValidateApp.szApplicationID_PID, _J("P42101")); /* regardless the application ID for copied one, it checks definition against P42101' */ jdeCallObject(_J("ValidateApplicationId"), NULL,lpBhvrCom,lpVoid,(LPVOID)&dsValidateApp, (CALLMAP *)NULL,(int)0,(JCHAR *)NULL, (JCHAR *)NULL,(int)0);
Purpose: Fetches and terminates the Sales Order Header memory allocations and any other allocations within the Sales Order Header
*** Break In Code *** JDECM_RESULT IB4210390_TerminateSalesOrderHeader(LPBHVRCOM lpBhvrCom,LPVOID lpVoid, HUSER hUser, HCACHE hCacheEx, JCHAR *szSessionKey) { *** Break In Code *** if (JDECMReturn == JDECM_PASSED) { if (IB4210390_GetSalesOrderHeader(lpBhvrCom, lpVoid, hUser, szSessionKey, &dsSalesOrderHeader)==JDECM_PASSED) { if(dsSalesOrderHeader.dsMetadata.cRecordReserved == _J('1')) { jdeStrcpy((JCHAR*)dsRemoveReservation.szNameObject, _J("F4211")); jdeStrcpy((JCHAR *)(dsRemoveReservation.szUserId), (const JCHAR *)(dsSalesOrderHeader.dsMetadata.szUserId)); jdeStrcpy((JCHAR*)dsRemoveReservation.szApplication, _J("P42101")); /* regardless the application ID, it release reservation against P42101 */ FormatMathNumeric(dsRemoveReservation.szGenericKey, &dsSalesOrderHeader.dsBusinessData.mnOrderNo); jdeStrcat(dsRemoveReservation.szGenericKey,dsSalesOrderHeader.dsBusinessData.szOrderType); jdeStrcat(dsRemoveReservation.szGenericKey,dsSalesOrderHeader.dsBusinessData.szOrderCo); jdeCallObject(_J("F00095RemoveReservation"), NULL,lpBhvrCom,lpVoid,(LPVOID)&dsRemoveReservation, (CALLMAP *)NULL,(int)0,(JCHAR *)NULL, (JCHAR *)NULL,(int)0); } *** Break In Code *** } *** Break In Code
Then turn on call object kernel log and review F00095 is recorded correctly when you update exiting sales order.
Note:
You may not be able to find referencing application through Cross Reference facilities because routine is handled through Business Function not Central Objects
Standard routine for record reservation, refer to <Document:1289755.1> - E1: BSFN: Record Reservation Related Business Functions in EnterpriseOne
In implementing above, the standard application P42101 will not record transaction to F00095 any more
In jdedebug.log, calling routine may appear like the following:
Depending on your EnterpriseOne release the object ID P42101 may not be a member of UDC 00/RR - Record Reservation
Object Reservation does not work for two different interactive application ID because there is only one business function (for this example, B4210010 - CreateSalesOrderFunctions) so,
UDC value P5542101 and Application ID P5542101 in function: record reservation does not take place in entering Sales Order through P42101
UDC value P5542101 and Application ID P42101 in function: UDC value P42101 need to be defined
UDC value P42101 and Application ID P5542101 in function: P42101 does not reserve record and UDC value has to be P5542101
UDC value P42101 and Application ID P42101 (No modification): UDC value P42101 has to be defined in UDC 00/RR
If possible, do not modify any definition made for Record Reservation