How to resolve the error - You have uncommitted work pending. Please commit or rollback before calling out?

2.0K    Asked by dipesh_9001 in Salesforce , Asked on Feb 24, 2023

This is my code at the moment, the API is only set to receive the ID's one at a time (if this is a major thing I can ask for this to be changed) so that I can send them in a batch instead. Also any comments to improve my code would be appreciative. I've only just started so I'm sure there will be improvements to be made.


public class sendToApi {
public static string token = 'test';
public static string sfid = '';
public static HttpResponse httpCallout() {
        
    // Format SF ID to send to API 
    string data = '{' + '"token": "' + token + '", ' +  '"sfid":' +  '"' + sfid + '"' + '}'; 
    Http http = new Http(); 
    HttpRequest request = new HttpRequest(); 
    request.setEndpoint('https://api.com'); 
    request.setMethod('POST'); 
    request.setHeader('Content-Type', 'application/json;charset=UTF-8'); 
    request.setBody(data);
    HttpResponse response = Http.send(request);
    System.debug('Http Response: ' + response);
    System.debug('Salesforce ID: ' + sfid);
    return response;
}
public static void updateRecord(DVLA_Lookup_Opportunity__c dv) {
    // dvlaOppToUpdate.Id = dv.Id;
    system.debug('sfid:' + dv.id);
    dv.SentToAPI__c = 'Sent';
    update dv;
}
@future (callout=true)
public static void dvlaUpdates() {
    
    // Create a list of account records from a SOQL query
    List dvla = [SELECT Id, SentToAPI__c, Account_Id__c FROM DVLA_Lookup_Opportunity__c WHERE Stage__c = 'Closed Won' AND SentToAPI__c = 'Pending']; 
    // Loop through the list and update the sfid field
    for(DVLA_Lookup_Opportunity__c dv : dvla) {
        sfid = dv.id;
        HttpResponse res = null; 
        res = httpCallout();
        if (res.getStatusCode() == 200) {
        updateRecord(dv);
        }
        else {
            System.debug(res.getStatusCode());
        }
    }
}
}
Answered by David EDWARDS

To resolve the error - You have uncommitted work pending. Please commit or rollback before calling out - you cannot perform a callout in a given transaction after performing DML. Your code currently does: callout -> dml -> callout for next record

Aside from that, you're performing DML inside of a loop (which is bad practice on the Salesforce platform, and likely to cause you to run into one of the governor limits).

If this API you're calling out to can (or can change to) accept multiple salesforce Ids, that'd be the way to go. Failing that, taking care of your "DML in loop" issue should also resolve the "uncommitted work pending" error. On the Salesforce platform, it's much preferred to work on collections of data rather than on single instances. Instead of calling updateRecord() on every record one at a time, you would gather the records to be operated on in a List, and send that List to your updateRecord() method (which also implies that you need to change the signature of that method).

public static void updateRecord(List dvList) {
    // Do your manipulation first, then perform DML after you're done processing
    // everything
    for(DVLA_Lookup_Opportunity__c dvItem vList){
        dv.SentToAPI__c = 'Sent';
    }
    update dvList;
}
@future (callout=true)
public static void dvlaUpdates() {
    List dvla = [SELECT Id, SentToAPI__c, Account_Id__c FROM DVLA_Lookup_Opportunity__c WHERE Stage__c = 'Closed Won' AND SentToAPI__c = 'Pending'];
    // Again, perform the work you want to do, and gather the results in a list.
    // THEN you can perform your DML
    List dvlaSuccess = new List();
    for(DVLA_Lookup_Opportunity__c dv : dvla) {
        sfid = dv.id;
        HttpResponse res = null;
        res = httpCallout();
        if (res.getStatusCode() == 200) {
            dvlaSuccess.add(dv);
        }
        else {
            System.debug(res.getStatusCode());
        }
    }
    // DML (and anything that performs DML) should be done outside of any loop
    updateRecord(dvlaSuccess);
}

Your Answer

Answers (2)

The tools really help when setting up programs. Build a geometry dash system of simple but connected programs. It's quite interesting when you update and share information sources. Reach out and learn more together to improve information security.

3 Months

The error message "You have uncommitted work pending. Please commit or rollback before calling out" typically occurs in programming when you're attempting to execute a database operation, like querying or updating data, while there are uncommitted changes in the current session. Here's how you can resolve it:


Commit or Rollback: Before executing any other database operation, make sure to either commit your current changes or rollback to discard them. If you intend to keep the changes, commit them using the appropriate command for your database (e.g., COMMIT in SQL). If you want to discard the changes, rollback using the ROLLBACK command.

Check Transactions: If you're working with transactions, ensure that you're properly managing them. If you've started a transaction but haven't committed or rolled it back, you'll encounter this error.

Check for Auto-commit: Some database systems have auto-commit enabled by default, which means each statement is treated as a separate transaction and automatically committed. If you've disabled auto-commit and haven't explicitly committed your changes, you'll encounter this error.

Review Code Logic: Review your code logic to ensure that database operations are properly ordered. Make sure that committing or rolling back is done at the appropriate places in your code.

Handle Exceptions: If an exception occurs during database operations, make sure to handle it properly. Ensure that your code catches exceptions and appropriately rolls back any changes to maintain data integrity.

Check for Nested Transactions: If you're working with nested transactions, ensure that you're handling them correctly. Each nested transaction should be properly committed or rolled back before moving to the outer transaction.

Test with Isolated Environment: If you're still encountering issues, consider testing your code in an isolated environment to identify any environmental factors causing the problem.

By following these steps and ensuring that your database operations are properly managed and ordered, you should be able to resolve the "uncommitted work pending" error.

Mongodb Failed: Error Connecting To Db Server: No Reachable Servers

The error "Error connecting to DB server: No reachable servers" in MongoDB typically indicates that your application is unable to establish a connection with the MongoDB server. Here are some steps you can take to troubleshoot and resolve this issue:

6 Months

Interviews

Parent Categories