Loading

Salesforce WebService Error - 'You have uncommitted work pending. Please commit or rollback before calling out'

Julkaisupäivä: Apr 24, 2026
Kuvaus

Callouts are not allowed when there is an uncommitted transaction pending. For example, if a savepoint is set before a Data Manipulation Language (DML) operation, a callout cannot be made based on the results of that operation to commit or roll back the savepoint.

Sometimes during the processing of records, your business rules require that partial work (already executed DML statements) is rolled back so that the processing can continue in another direction. Apex gives you the ability to generate a savepoint, that is, a point in the request that specifies the state of the database at that time. Any DML statement that occurs after the savepoint can be discarded, restoring the database to the condition it was in when you generated the savepoint. 

Example scenario:
When trying to perform a savepoint, insert an account to find duplicates and rollback and then perform a webservice callout to send the account data to an external system. But before the webservice is called, you may see the error 'You have uncommitted work pending. Please commit or rollback before calling out.'
 

The following steps might result in this error: 
  1. Enter data in the user interface to create a new customer and click Save
  2. System creates a save point and then inserts the customer record. 
  3. Triggers fire to find duplicates.
  4. If there are no duplicates, it will roll back the customer record insert based on the savepoint set in step 2. 
  5. System will call a web service to send the new customer data to an external system and get an external ID back.
  6. System stores the new customer in SFDC along with the external ID.
The other scenarios include uncommitted work through Async enqueue processes like System.enqueueJob, Database.executeBatch, and Future methods. 
Ratkaisu

To resolve the "You have uncommitted work pending" error in Salesforce Apex, restructure your code so that all callouts are made before any DML operations. It is not possible to perform an explicit commit in Apex. Move callout logic to a separate execution context if needed.

Correct Operation Order

Execute operations in this sequence to avoid the error:

  1. SOQL query
  2. Callout
  3. SOQL query
  4. Callout
  5. Additional callouts as needed
  6. DML insert or update (after all callouts are complete)

Incorrect Operation Order

This sequence causes the error:

  1. Callout
  2. DML insert
  3. Callout ← fails here because a pending DML transaction exists

Resolution Options

  1. Make the callout prior to any database changes, or move your callout to a @future method by placing the @future(callout=true) annotation on the web service method.
  2. Split the transaction into two separate processes. The first process inserts the record; the second performs the callout and updates the newly inserted record.
  3. Save the records and return a temporary "Loading" page to the user while making a second AJAX call to perform the callout, making the experience appear seamless.
  4. If you do not want to use @future, execute an action to insert the object and then execute the web service callout on the oncomplete event of a command button. Return a PageReference for immediate user feedback. If the callout returns an error, delete the object and return the user to the original page.

Visualforce and Apex Code Example

The following Visualforce page uses oncomplete to trigger the callout after the save action completes, keeping DML and callout in separate execution contexts:
Visualforce Page: The page uses an apex:actionFunction named executeWS bound to the controller action executeWS, and an apex:commandButton with action save and oncomplete="executeWS()".
Controller: The save() method inserts the object. The executeWS() method queries the inserted object, makes the callout, and on success returns a PageReference. If the callout fails, it deletes the object, adds the error message, and returns null.

 

Visualforce Page :
<apex:actionFunction name="executeWS" action="{!executeWS}"></apex:actionFunction>
 <apex:commandButton value="Save" action="{!save}" oncomplete="executeWS()" />
Controller :
public PageReference save() {
 insert obj;
}
public PageReference executeWS(){
 obj = [SELECT ...];
 try{
 callout ws;
 } catch(System.Exception ex){
 delete obj;
 ApexPages.addMessages(e);
 return null;
 }
 return new PageReference('/' + id);
}

Knowledge-artikkelin numero

000385708

 
Ladataan
Salesforce Help | Article