BPM, requires a pause for 1 second

Hi, any suggestions on how to make a bpm pause for 1 second?
The bpm auto approves a PO requisition mandatory action if certain conditions have been met, it is triggered just after the requisition has been dispatched to that action. The dispatch and approval actions each write a record to the table ReqLog, however the primary key for this table comprises:

Company,
ReqNum,
ChangeDate,
ChangeTime,
ReqLogType.

ChangeTime is in seconds and since both of the two writes occur consecutively the system throws a duplicate primary key error.
My thoughts were to pause the approval bpm for one second with a custom code c# function, any suggestions how this could be coded? Or any other ideas how to overcome the problem, can the bpm piggy back onto some scheduled activity? I had thought of forcibly incrementing the field ReqLogType, but instinct tells me this could cause problems elsewhere.
Thanks and regards
neil

This in a custom code block will pause the BPM for 1000msec
System.Threading.Thread.Sleep(1000);

However, pausing for 1 sec is not a good solution, hopefully some of the smart people here can offer you better ideas :slight_smile:

Brett

I have had related problems with some projects and never found a fully satisfactory answer. Whenever I have introduced a pause in a BPM, everything pauses in lockstep and the problem still occurs after the pause. So Iā€™ll be interested to see if anyone does have a good solution to that.

Two strategies have usually got me around the issue:

  1. Split your updates into two custom code blocks in the BPM and set the second one to run async. Often that gives just enough of a time gap (and solves the threading problem) that everything sorts out tidily.
  2. Remove part of the routine out of the BPM and put it in Service Connect, either triggered from the BPM or by something the BPM does, and let it handle the things that need to happen later.

But as I say, Iā€™ll be interested in anyone elseā€™s take on the problem.

Hi @drbgrup
when you say ā€œboth writing to the same tableā€, is your BPM triggering the two actions on one method run or on two different methods? could you screen shot some details ? as per my understanding to Epicor logic and behaviour if two methods writing to the same table either this table must have a field to identify the source or one of them to ā€˜Addā€™ the record and the other one to ā€˜Updateā€™, thereby you can use the RowMod status and add it to your trigger conditions.

based on that, just thinking if you can move the validation to be pre-processing BPM and save all needed relevant key values to callcontextvariables with trigger flag, then invoke the approval method on your post-processing BPM if this flag is true and pass all your key values from the contextvariables and/or the rest from the tttable,

How about for your time key, on whichever the second one is, instead of current time, make it current time + 1 second (or 2 just for a safe gap). The record will be 1 second off real time, but that should get both of these records committed. As long as you are only running the BPM once every two seconds max.

The best answer would be to make one of the keys into a GUID so they never match. But Iā€™m guessing you may be too far in the process to change it.

edit I was thinking this was writing to a UD table, so you canā€™t change the keys.

Thanks for your reply guys.

Hi A.Baeisa

Hereā€™s how I see the process flow.

The first write is invoked normally in the (unmodified) Base Processing of the ā€˜Updateā€™ method of the business object Req, initiated by user action on the Requisition Entry form.

The second write is invoked in my Pre-BPM on the method ā€˜RDMenuFlagsā€™ of the business object Req. I have hooked into this method for no other reason than it always follows the Update method.

I Have attached some screen grabs that illustrate in more detail the process flow, as far a I can see the problem is with the 2nd write occurring within the same second as the 1st write. If only the PK field ChangeTime was in milliseconds.

Thanks.

ReqLog duplicate key.docx (362.6 KB)

I say put a Data Directive on ReqLog table In-Transaction which checks to see if the keys already exist and if so, add 1 to ChangeTime. Putting a pause on a BPM is really really bad idea.

3 Likes

forgive my ignorance as our finance department do not use the financial module, so i have not done any work on this area, but reading through your tech. spec. document, and -correct me if i am wrong- you are trying to hook to a system flag method ā€˜RDMenuFlagsā€™ and intercept it by passing parameters that already exist on the ###Base## run that is why you will end up having double records.

If i were you as i explained before just capture these key values in callcontextvariables with an extra true/false flag then find the actual method which runs when the requisitions get approved manually, invoke it and pass the relevant parameters to it in post-BPM on req-Update

Joseā€™s suggestion works nicely and it feels ā€˜rightā€™ with being implemented so to close the where the issue was occurring. Thanks again to everyone for your input. I hope to be able to give back one day.
Cheers
neil

1 Like

@josecgomez did not work in my case, but I came up with an alternative that seems slightly better.
The issue I had with a Data Directive that added 1, was that it was still the same second, so it was still a duplicate. I tried checking for the duplicate first but it didnā€™t find one, not sure if I did something wrong or not. (it was Epicor 10.0). This was the Mass Part Number replace and some methods they had the same part on the method twiceā€¦ No idea whyā€¦ there were thousands of Methods.
I ended up setting ttPartAuditChangeTime =
ttPartAuditRow.ChangeTime + ((BpmFunc.Now().Millisecond)/100)

I didnā€™t want to add a thousand seconds but I wanted something with more precision.
Worked in my case.

1 Like