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

2 Answers 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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .