0

I create the batch class for making a callout and updating contact records but while running batch class getting the "Apex CPU time limit exceeded" exception. Please see the details below

i am passing only one rates record to execute method for makeing a callouts. callouts succesfully executed and get the response from external system. once i get the resposne from external system then i am updating Exchange_Rate_Updated__c field with system.now on contact object. SELECT Id FROM Contact WHERE Type__c='simple' query returning 800 reocrds but i can't able to update the 800 records because system throughing "Maximum CPU time: 65086 out of 60000 ******* CLOSE TO LIMIT" exception. Please see the code below

public class CurrencyExchangeRate implements Database.batchable<sObject>,Database.AllowsCallouts
{

    test_setting__c cc=test_setting__c.getInstance('SetupOwnerId');
    Id ownerId = cc.Value__c;

    String query = 'SELECT Id,AUD_Exchange_Rate__c,Buffer_Rate__c, CAD_Exchange_Rate__c,CHF_Exchange_Rate__c,EUR_Exchange_Rate__c,MXN_Exchange_Rate__c,NZD_Exchange_Rate__c,PLN_Exchange_Rate__c,SGD_Exchange_Rate__c,USD_Exchange_Rate__c,Currency_updated_date_time__c FROM Exchange_Rates__c Where SetupOwnerId=\'' + ownerId + '\'';

    public Database.querylocator start(Database.BatchableContext BC)
    {
        return Database.getQueryLocator(query);
    }

    public void execute(Database.BatchableContext BC, List<Exchange_Rates__c> rates)
    {
        system.debug('RATES ####'+rates);

        String response;

        List<ECS__Product__c> lstupdate = new List<ECS__Product__c>();

        Map<String,test_setting__c> mapcurrency = test_setting__c.getAll();
        String BaseURL =  mapcurrency.get('BaseURL').Value__c;
        String ACCESS_KEY = mapcurrency.get('ACCESS_KEY').Value__c;
        String Currencies = mapcurrency.get('Currencies').Value__c;
        String Endpoint = mapcurrency.get('EndPoint').Value__c;
        String Source = mapcurrency.get('Source').Value__c;
        String OwnerId = mapcurrency.get('SetupOwnerId').Value__c;

        String URL = BaseURL+Endpoint+'?access_key='+ACCESS_KEY+'&currencies='+Currencies+'&source='+Source+'&format=1';
        system.debug('RequestURL ####'+URL);

        Http h=new Http();

        HttpRequest req=new HttpRequest();
        req.setHeader('Content-Type','application/json');
        req.setHeader('Accpt','applicatoin/json');
        req.setEndpoint(URL);
        req.setMethod('GET');
        req.setTimeOut(60000);

        HttpResponse res=new HttpResponse();

        if(!Test.IsRunningTest())
        {
          res=h.send(req);
          response = res.getBody();
        }else{
          MockHttpResponseGenerator mr=new MockHttpResponseGenerator();
          res = mr.channelAdvisorResponed(req);
          response = res.getBody();
        }

        system.debug('RESPONSE ####'+response);

        CurrencyDTO cs=parse(response);
        system.debug('CS ####'+cs);

        system.debug('GBPEUR ####'+cs.quotes.GBPEUR);
        system.debug('GBPCHF ####'+cs.quotes.GBPCHF);
        system.debug('GBPUSD ####'+cs.quotes.GBPUSD);
        system.debug('GBPCAD ####'+cs.quotes.GBPCAD);
        system.debug('GBPMXN ####'+cs.quotes.GBPMXN);
        system.debug('GBPAUD ####'+cs.quotes.GBPAUD);
        system.debug('GBPNZD ####'+cs.quotes.GBPNZD);
        system.debug('GBPSGD ####'+cs.quotes.GBPSGD);


        if(cs.success ==true)
        {
          rates[0].EUR_Exchange_Rate__c = cs.quotes.GBPEUR;
          rates[0].CHF_Exchange_Rate__c = cs.quotes.GBPCHF;
          rates[0].USD_Exchange_Rate__c = cs.quotes.GBPUSD;
          rates[0].CAD_Exchange_Rate__c = cs.quotes.GBPCAD;
          rates[0].MXN_Exchange_Rate__c = cs.quotes.GBPMXN;
          rates[0].AUD_Exchange_Rate__c = cs.quotes.GBPAUD;
          rates[0].NZD_Exchange_Rate__c = cs.quotes.GBPNZD;
          rates[0].SGD_Exchange_Rate__c = cs.quotes.GBPSGD;
          rates[0].PLN_Exchange_Rate__c = cs.quotes.GBPPLN;
          rates[0].Currency_updated_date_time__c = system.now();

          update rates[0];

          //Map<Id,ECS__Product__c> lstMap = new Map<Id,ECS__Product__c>([SELECT Id,Name,ECS__Product_Type__c,Ignore_Exchange_Rate__c FROM ECS__Product__c WHERE Ignore_Exchange_Rate__c=False and ECS__Product_Type__c='Simple']);
          //system.debug('LSTMAP ####'+lstMap.size());

         // if(lstMap.size()>0 && !lstMap.isEmpty())
          //{
            for(List<ECS__Product__c> eslst:[SELECT Id,Name,ECS__Product_Type__c,Ignore_Exchange_Rate__c FROM ECS__Product__c WHERE Ignore_Exchange_Rate__c=False and ECS__Product_Type__c='Simple' and Name='sssssssss'])
            {
                for(ECS__Product__c es:eslst)
                {
                    es.Exchange_Rate_Updated__c = system.now();
                    lstupdate.add(es);
                }
            }
          //}

          system.debug('LSTUPDATESIZE ####'+lstupdate.size());
          system.debug('LSTUPDATE ####'+lstupdate);
        }

        if(lstupdate.size()>0 && !lstupdate.isEmpty())
        {
          update lstupdate;
        }
}

public void finish(Database.BatchableContext BC)
{

}

 // Parse the Response ***//
 public static CurrencyDTO parse(String Response)
 {
    return (CurrencyDTO) system.Json.deserialize(Response,CurrencyDTO.class);
 }

 public class CurrencyDTO
 {
    public boolean success {get;set;}
    public String terms {get;set;}  
    public String privacy {get;set;}    
    public Integer timestamp {get;set;} 
    public String source {get;set;}
    public Quote quotes {get;set;}

    public CurrencyDTO(boolean Success,String terms,String privacy,Integer timestamp,String Source,Quote Quotes)
    {
        this.success = Success;
        this.terms = Terms;
        this.privacy = privacy;
        this.timestamp = timestamp;
        this.source = source;
        this.quotes = quotes;
    }
  }

  public class Quote
  {
    public Double GBPEUR {get;set;}
    public Double GBPCHF {get;set;}
    public Double GBPUSD {get;set;}
    public Double GBPCAD {get;set;}
    public Double GBPMXN {get;set;}
    public Double GBPAUD {get;set;}
    public Double GBPNZD {get;set;}
    public Double GBPSGD {get;set;}
    public Double GBPPLN {get;set;}

    public Quote (Double GBPEUR,Double GBPCHF,Double GBPUSD,Double GBPCAD,Double GBPMXN,Double GBPAUD,Double GBPNZD,Double GBPSGD,Double GBPPLN)
    {
        this.GBPEUR = GBPEUR;
        this.GBPCHF = GBPCHF;
        this.GBPUSD = GBPUSD;
        this.GBPCAD = GBPCAD;
        this.GBPMXN = GBPMXN;
        this.GBPAUD = GBPAUD;
        this.GBPNZD = GBPNZD;
        this.GBPSGD = GBPSGD;
        this.GBPPLN = GBPPLN;
    }
  }
}
ho

w can fix this issue. Could you please help on this.

  • is it the complete code?where are you making callouts and where is the query in start method ? – Anurag A Aug 10 '16 at 15:47
  • Confused -- you are updating Contacts in execute() but the query locator is on Rates__c . Wouldn't you be getting Rates via callout in Constructor and then querying Contacts in start method? All those Contact updates could be executing triggers – cropredy Aug 11 '16 at 1:43
  • 1
    (1) in the code you posted - there is no update on Contacts, instead - something called ECS__Product__c; (2) you posted lots of irrelevant code - delete it from OP using edit; (3) is sandbox a fullcopy sandbox or just a dev sandbox - # of records queried will vary and could affect runtime. Try and mimic PROD in sandbox at least with respect to record volume - you have Limits class that can help you put debug in code to see where cpu time is going (i.e. instrument code) – cropredy Aug 11 '16 at 13:39
  • 1
    You should look up Hierarchy Custom Settings... – Adrian Larson Aug 11 '16 at 14:08
  • 1
    isn't this a duplicate of salesforce.stackexchange.com/questions/136411/… ? – cropredy Aug 12 '16 at 6:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.