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


*** 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);

if(dsValidateApp.cValidateApplication_ERR1 == _J('0'))
{
jdeStrcpy((JCHAR *)dsDX00022AParms.szObjectName, _J("F4211"));
idReturnValue = jdeCallObject(_J("GetNextUniqueKeyID"), NULL,
lpBhvrCom, lpVoid, (LPVOID)&dsDX00022AParms,
(CALLMAP *)NULL, (int)0, (JCHAR *)NULL,
(JCHAR *)NULL, (int)0);
if(idReturnValue == ER_SUCCESS)
{
MathCopy( &dsD0000045.mnMathNumeric01 ,&dsDX00022AParms.mnUniqueKeyID);
idReturnValue = jdeCallObject(_J("ConvertNumericToString"),(LPFNBHVR)NULL,lpBhvrCom,lpVoid,&dsD0000045,
(CALLMAP*)NULL,0,(JCHAR*)NULL,
(JCHAR*)NULL,0);
if(idReturnValue == ER_SUCCESS)
{
jdeStrcpy((JCHAR*)dsReserveOrder.szApplication, (const JCHAR *)dsD0000045.szVideoConstant30A);
}
}
jdeStrcpy((JCHAR*)dsReserveOrder.szNameObject, _J("F4211"));
jdeStrcpy((JCHAR *)(dsReserveOrder.szUserId), (const JCHAR *)(lpdsSalesOrderHeader->dsMetadata.szUserId));
dsReserveOrder.cSuppressErrorMessage = _J('1');
FormatMathNumeric(dsReserveOrder.szGenericKey, &lpdsSalesOrderHeader->dsBusinessData.mnOrderNo);
jdeStrcat(dsReserveOrder.szGenericKey,lpdsSalesOrderHeader->dsBusinessData.szOrderType);
jdeStrcat(dsReserveOrder.szGenericKey,lpdsSalesOrderHeader->dsBusinessData.szOrderCo);
jdeCallObject(_J("F00095ReserveObject"),
NULL,lpBhvrCom,lpVoid,(LPVOID)&dsReserveOrder,
(CALLMAP *)NULL,(int)0,(JCHAR *)NULL,
(JCHAR *)NULL,(int)0);
*** Break In Code ***
}
*** Break In Code ***



B. Remove Reservation


*** 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: √ (Reservation) P42101 - Sales Order Entry
|--- W42101D_CreateSalesOrder
|--- F00095ReserveObject

√ (Release Reservation) P42101 - Sales Order Entry
|--- SalesOrderApplCtrlEX
|--- F00095RemoveReservation
(This is correct result in MVC Architecture)

Back To Top

Summary:

Back To Top