1

Today i recived an exception mail saying this :

Exception Message: Upsert failed. First exception on row 0; first error: UNABLE_TO_LOCK_ROW, unable to obtain exclusive access to this record: []

I searched the meaning of this error and found this:

This is something temporary and would be fixed automatically in 10-15 minutes maximum. Some common causes are - 1. Sharing Rules are being calculated. 2. A picklist value has been replaced and replacement is in progress. 3. A custom index creation/removal is in progress. 4. Most unlikely one - someone else is already editing the same record that you are trying to access at the same time.

The thing is our platform doesn't have an autoretry and my org told me to try doing that on the web service callout.

My initial idea about how to deal with this would be this : -We do the WS callout, when we get an exception, we analize the code of it, if it's de UNABLE_TO_LOCK_ROW error then we should schedule another callout after 15 minutes. We could also add some kind of logic to avoid infinite loops(wich however shoudn't be happening if the exception definition i found is correct)

The problem is i have no idea if its even posible to retry that callout with a deadtime of 10-15 minutes. Is it?

I'm not demanding obviously the solution code , just a general guideline to know if this is possible, and in afirmative case, how can i make the best approach to the optimal solution.

Thanks!

  • 3
    You can schedule code to run in the future and if the future call fails schedule again. You will have to do the work in method marked @future(callout=true). – Keith C Jun 2 '15 at 13:53
  • 1
    It's pretty ironic since i've worked some other times with Scheduled jobs, but mostly with Batches, so i didn't really realized how to initially. I guess i only have to pass through parameter the JSON and retry the call and that's all, am i right? – Alexander Aeons Torn Jun 2 '15 at 13:56
  • 2
    Yeah for @future its "primitive data types, arrays of primitive data types, or collections of primitive data types" and JSON is a good way of packing information into that form. – Keith C Jun 2 '15 at 14:02
  • This is possible in Apex. I believe a simple try catch mechanism where catch blocks are structured from most specific to least specific should do the trick instead of writing an if-else block. And have an ExceptionManager class route the control to the necessary components that schedules a job after a specific time interval say 15 seconds and performs a retry to the callout. – Jigar Shah Jun 2 '15 at 14:20
3

Others have recommended scheduling a job as a result of catching the WS exception, but that's not something I feel comfortable with due to the possibility that the scheduling of the remediation-job fails due to too-many-jobs, etc. If the result of the WS is critical to the business (processing a $10M deal), then there can't be any risk that the follow-up does not occur.

The pattern I've used to resolve this is a continuously running job that checks a queue (Follow_Up_Queue__c) for actions to take. The queue item will indicate the action the job needs to take, and in your case it would be to re-attempt the callout. This means the queue item will need enough info in the record to setup the same WS call again, so you may need lookups to the source records or perhaps stashing WS call parameters.

Then when your job runs (say every 15 minutes), a batchable class breaks up the contents of the queue (to avoid limits) and executes the pending action.

Google around Scheduled Apex Job Chaining (validated by the community and works) or look a the new Queueable interface (which appears to have problems with WS callouts based on the comments in that article; perhaps not ready for this use case yet).

I have personally implemented Scheduled Apex Job Chaining at a continuous 5 minute interval, processing queued callout actions, and it works like a charm. Simply log the results of each action and monitor for actions that are continuously failing (report?) to catch the corner case where exceptions are NOT being resolved after multiple attempts. In my case, I've implemented a countdown of 3 attempts before recategorizing from pending action to unresolvable error in need of manual resolution. In your case, you might want the action to requeue indefinitely.

I believe there's a detailed implementation in Dan Appleman's Advanced Apex.

| improve this answer | |
  • I'm actually working on this, as soon as i can say if it worked for my org i will. Thanks. – Alexander Aeons Torn Jun 3 '15 at 13:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.