0

I have two sets of 250k records I need to update in production. I am trying to figure out the best way to attack it. I need to hit a webservice that has a future callout, and then take the data to update records.

I originally wrote some Batch APEX and was getting back a limits error: "Future method cannot be called from a future or batch method". As you can see in this article, Batch Apex does, in fact, not support future callouts: http://help.geopointe.com/customer/portal/articles/1767162-future-method-cannot-be-called-from-a-future-or-batch-method

I then did some research and included a Queueable class but am still getting a limits exception: "Too many future calls: 51". This to me means that the Queable method might allow Batch to happen on Future but I need to handle it differently, or I am writing the code wrong. I tried manipulating my code so that the webservice would only get hit once with a list of data but I found that I would have to majorly change the rest of my code to get this to work.

My last resort would be to give our Principal Software Developer a CSV and ask him to try and run it along with his webservice. But I am not sure if he can even do this.

Could anyone tell me if it is possible at all to do Batchable on future calls? Or am I spinning my wheels?

global class BatchableEncryptedEmailBackfill implements Database.Batchable<sObject>,Database.AllowsCallouts,Database.Stateful{

global final String Query;
global final String Entity;
global final String Field;
global final String Value;
global static List<Lead> changedLeads;

global Database.QueryLocator start(Database.BatchableContext BC){
    String query = 'SELECT Id, Web_Id_NatFund__c FROM Lead WHERE pi__url__c != NULL AND Encrypted_Email_String__c = NULL';
    return Database.getQueryLocator(query);
}  

global void execute(Database.BatchableContext BC, List<Lead> listLead){
    System.enqueueJob(new QueueClass(new Map<Id, Lead>(listLead).keySet()));
    /*for(Lead l: listLead) {
        if(l.Web_Id_NatFund__c != NULL) {
            String val = l.id + ',' + l.Web_Id_NatFund__c;
            ConsoleApplicationLinkController.getShortenedLinkBACKFILL(val);
        }
    }*/
}

global void finish(Database.BatchableContext BC){
    system.debug('got into finish:' + BC);
}
public class QueueClass implements Queueable {
    Set<Id> recordids;
    public QueueClass(Set<Id> recordIds) {
        this.recordIds = recordIds;
    }
public void execute(QueueableContext context) {
    for(Lead l: [SELECT Id, Web_Id_NatFund__c FROM Lead WHERE pi__url__c != NULL AND Encrypted_Email_String__c = NULL]) {
        if(l.Web_Id_NatFund__c != NULL) {
            String val = l.id + ',' + l.Web_Id_NatFund__c; 
            ConsoleApplicationLinkController.getShortenedLinkLT(val); //webservice
        }
     }
}
}

1 Answer 1

2

You can't call asynchronous code from code that's already asynchronous.

Can you just not have the problem in the first place? ;) Is there a version of the function that does what you need but it's not marked @future? Worst case - create a clone of that @future function without annotation (and make the future version call this new function so there's no code duplication).

Then a normal batch shouldn't have any problems, no need to drag Queuable into this.

Alternatively - just prepare a snippet of code that does what you need (copy-paste pieces of start() & execute()) and works on 10K records or less (SELECT ... LIMIT 10000; you might have to pick a lower value if there are side effects of Lead update). You'll have to run it from Developer Console 25 times. It's a boring task - but if it's an one-off data fix making a whole batch class & providing unit tests for it is an overkill.

1
  • all great suggestions. When I call the cloned version of the future method, I am able to get into it BUT I just realized that if I do a batch of records that have a webservice call out, and then DML that handles the webservice data, it will loop through again creating DML to happen before the webesrvice. It'll be: webservice-> dml -> webservice -> DML....Which will error out. So now I have to handle this...
    – Olivia
    Oct 10, 2017 at 23:41

You must log in to answer this question.

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