I am getting an exception of System.CalloutException: You have uncommitted work pending. Detail of the Exception is given Below:

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

I am using Apex for calling a Webservice. Based on the data returning from the WebService, performing upsert operation in Salesforce Instance. I am performing the following operation on the Salesforce Instance.

1 Performing upsert operation in Campaign Object.

2 Performing upsert Operation in Account Object.

3 Performing upsert Object in Contact Object using AccountID of the earlier inserted Account.

4 Then Adding Contacts as CampaignMember in the Campaign that I have Created earlier.

My code is working fine when There is only one record in the Webservice API but when there are more than one record in the API then getting the Exception of System.CalloutException: You have uncommitted work pending. I have spend one week but did not able to get rid off the exception.

Any help will be much appreciated.

Thanks in advance.

  • 1
    Can you post the code snippet? – Ashwani Dec 14 '15 at 13:11
  • 2
    The problem here is that you have inserted, updated or deleted some records in the database before making the call to the webservice. This is not allowed in Apex. You should save all the database calls until after the call to the webservice. – rael_kid Dec 14 '15 at 13:12
  • 1
    As Lex mentioned above, this looks like you're doing some DML before calling the webservice. You should make all your DML calls after the callout. The implementation details depend on your specific problem. It would be good if you could post your code so that we can help you better. – mkorman Dec 14 '15 at 14:29

You are not allowed to perform any DML operations before making any type of callout. You will need to process all callouts first (this might mean having a for loop for just your callouts first), store the results of each callout, then process your records and DML after.

Why is this? When you perform a DML operation, you are granted a database connection. You hold on to this connection until the end of your context to allow for rollbacks in the event of an error. When you make a callout, Salesforce gives you up to 120 seconds to wait for the response from that endpoint. If you were holding on to that Salesforce database connection for 120 seconds to allow for transaction control this would cause a serious performance issue for Salesforce.

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