1

I am on occasion seeing a "You have uncommitted work pending. Please commit or rollback before calling out" error during a sequence of callouts that are part of the same transaction. So basically the transaction is going:

  • callout

  • callout

  • callout

  • update records

However I am now noticing that on those callout methods there is code to update a record holding the OAuth token if the first callout fails due to unauthorized token. This method is tagged as @future(callout=true). So each callout goes:

  • callout

  • if unauthorized, callout for authorization, call @future method with updated OAuth token to update a record and save the new auth token

  • callout again with updated auth token

So there's a chance every now and then that when the OAuth token expires, the next callout could fail because it's running DML in between callouts in the same transaction. I was under the impression that an @future method executes in its own context outside of the transaction, but I am not seeing that happen. Am I misunderstanding the @future annotation?

Thanks

2
6

Executing a @future method counts as DML for the purposes of mixing callouts and DML. You can demonstrate it for yourself with a simple Minimum Viable Reproduction (MVR).

public with sharing class Demo
{
    @future
    public static void doNothing() { }
    public static void verifyCalloutBehavior()
    {
        doNothing();
        new Http().send(new HttpRequest());
    }
}

Then just run an anonymous script where you call Demo.verifyCalloutBehavior();. You'll get the expected error.

System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out

0

Per Salesforce (here, and here), you cannot make any callouts after DML. Your second bullet 'update a record and save the new auth token' before your third bullet (callout) suggests a mid-stream DML, resulting in your error.

To combat this problem, you must either reserve your DML updates until when all callouts are complete, or you could build another trigger/handler method that does the final callout separately as a result of the update to your OAuth token.

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.