0

I am trying to do three operation using same record.

First Operation: Set ContentDocument isArchived field to false.

Second Operation: Grab contentdocument by calling REST API Endpoint.

Third Operation: Set ContentDocument isArchived field to true.

When I ran the logic by clicking on a button, isArchive was set to false but then got message, "you have uncommitted work pending. please commit or rollback before calling out". Also isArchive being false was also persisted in database. So, I had to manually set isArchived to true again. I tried to use savepoint and rollback but it gave me the same error.

Map<Id, ContentDocument> docMap = new Map<Id, ContentDocument>();
Savepoint sp;
List<ContentDocument> contDocs = new List<ContentDocument>();
public void doOperations() {
    operation1();
    operation3(); //operation2() called from operation3()
}


void operation1(){
//sp = Database.setSavepoint();
ContentDocument doc= [select id,IsArchived from ContentDocument where id = docMap.get(Id);
    if(doc.isArchived == true) {
        doc.isArchived = false;    
        update doc;
        contDocs.add(doc);
    }
}

void operation2(Id contentId) {
    //call restendpoint and retrieve contentDocument
}

void operation3(){
    operation2();
  // Database.rollback(sp); 
    for(integer i=0; i<contDocs.size(); i++){
        contDocs[0].isArchived = true;
        contDocs[1].isArchived = true;
    }
     update contDocs;
}

The doOperations is action method called from visualforce page. Is it possible to run all operations when a user clicks on a button.

I used rollbacks as well but could not solve the problem. Rollback and savepoint in above code is commented but even without commenting, could not resolve issue.

Edit: I know there are other question like this but i want to perform every operation synchronously. I cannot use future methods here.

Any idea/help on this.

marked as duplicate by Renato Oliveira, David Reed apex May 17 at 0:55

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Sorry for not putting this before, I want to do all the operations synchronously. This is not a duplicate. – lambad May 17 at 1:02
  • You can't do those three things in that order in one transaction. – David Reed May 17 at 1:48
  • @DavidReed, Can i do the operations in multiple transactions such that the first, second, third operations should be called one after another. Once the third operation finishes, the response will be shown in an iframe (canvas app) – lambad May 17 at 1:56
  • Not voting to reopen. This is a well known limitation. You must perform all callouts before any of your DML. Simply move your update calls out of operation1 and into the end of doOperations. Some quasi-DML statements also count for this limitation, and definitely setting or rolling back to a savepoint. – Adrian Larson May 17 at 3:02
  • @AdrianLarson The problem is using operation2, I will retrieve public download urls for contentdocument. Because the contents are archived, I cannot retrieve their download urls. So, I need to set isArchived field of contentDocument to false (done in operation1) and then only i can hit a rest endpoint and get public download urls. – lambad May 17 at 3:17