function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Miguel RoaMiguel Roa 

FATAL_ERROR System.LimitException: Too many queueable jobs added to the queue: 2

Hello, I have this class that is excecuted by a Batchable

And I getting the following error on the log: FATAL_ERROR System.LimitException: Too many queueable jobs added to the queue: 2

According to some posts that I've read, the issue is because I have system.enqueueJob(dvssService) inside a for loop.
 
public without sharing class OpportunityUpdate_WithDVSSCaseHelper {
    
    public static void UpdateOpptyStatusForOpptyWithDVSSCases_OnPegaSide(List<Opportunity> newOppty,Map<Id,Opportunity> oldOppty){
      
        Map<String,String> DvssCaseTypes = new Map<String,String>();
        DvssCaseTypes.put('DVSS AM', 'DVSSAM'); 
        DvssCaseTypes.put('DVSS CPE','DVSSCPE');
        DvssCaseTypes.put('DVSS DR','DVSSDR');
        DvssCaseTypes.put('DVSS RFP','DVSSRFP');
    
        List<Id> opptyIds = new List<Id>();
        List<Opportunity> opptiesToUpdateOnPega;       
        for(Opportunity oppty:newOppty){
            
            Opportunity oldOp = oldOppty.get(oppty.Id);
            if(oppty.StageName != oldOp.StageName && (oppty.StageName =='5 Closed Lost' || oppty.StageName =='5 Closed Disqualified' ) ){
                opptyIds.add(oppty.Id);
            }
            
        }   
        
        
        if(opptyIds.size() > 0){
            
            
            opptiesToUpdateOnPega = [select Id,StageName,(SELECT Case_Type__c,SWAP_Case_ID__c FROM SWAPS_Tracker__r where case_type__c in ('DVSS AM','DVSS CPE','DVSS DR','DVSS RFP')) 
                                     from Opportunity where Id in:opptyIds and Id in(select Opportunity_Name__c from SWAP_Tracker__c
                                                                                     where Opportunity_Name__c in:opptyIds and case_type__c in ('DVSS AM','DVSS CPE','DVSS DR','DVSS RFP')) ];

            
            if(opptiesToUpdateOnPega.size() > 0){
             
                               
                
                for(Opportunity opp:opptiesToUpdateOnPega){
                    
                    List<SWAP_Tracker__c> swTrack = opp.SWAPS_Tracker__r;
                    
                    system.debug('Oppt info LP>> ' + opp);
                    DateTime dtvar = null;
                    String Casetype='' ;
                    String CaseId='';
            
                    string OpptyStatus = opp.StageName;
                    
                    
                        for(SWAP_Tracker__c swt:swTrack){
                            
                            Casetype =  (DvssCaseTypes.get(swt.Case_Type__c) == null)?'':DvssCaseTypes.get(swt.Case_Type__c);
                            CaseId = (swt.SWAP_Case_ID__c ==null)?'':swt.SWAP_Case_ID__c;
     
                           
                DVSSOpptyStageUpdateService dvssService = new DVSSOpptyStageUpdateService();
                dvssService.Casetype = Casetype;
                dvssService.CaseId = CaseId;
                dvssService.OpptyStatus = OpptyStatus;
                
                system.enqueueJob(dvssService);                
                
            }  

            
            
        }


        
        
     }


   }

}
        
    public class DVSSOpptyStageUpdateService implements Queueable, Database.AllowsCallouts {
        

        public string Casetype{get;set;}
        public string CaseId{get;set;}
        public string OpptyStatus{get;set;}
        
        
        
        public void execute(QueueableContext context){
            
            

            
            system.debug('LL- Calling to update oppty stage');
            
            try{
                
            
                        Pega_CaseMiddleware.PegaCaseResult pagecaserslt = Pega_CaseMiddleware.UpdateDVSSCases_OpptyStatus(Casetype,CaseId,OpptyStatus);
                        
                        If(pagecaserslt.Error.size()>0){                
                            
                            system.debug('LL- error Message>>> ' + pagecaserslt.Error);
                            
                            
                            
                        }
                        else{
                            
                            system.debug('LL- Success Message>>> ' + pagecaserslt.CaseID);
                            
                        } 
                        
                
                
                
            }
            catch(Exception ex){
                
                system.debug('LL-Errrrror: ' + ex.getMessage()+ ' -- ' + ex.getStackTraceString() + '-- ' + ex.getLineNumber());
                insertLog('outbound', '-1', ex.getMessage()+ ex.getStackTraceString() + ex.getLineNumber(), 'DVSSOpptyStageUpdateService');    
                
            }
            
            
        }
        
        
    }
    
    public static void insertLog(String inboundOutbound, string requestID, string message, string method){
        
        try {
            
            Event_Log__c log = new Event_Log__c();
            
            log.Record_Id__c = requestID;
            log.Operation__c = inboundOutbound;
            log.sObject_Type__c ='SWAP Case';
            log.Message__c = 'pega_salesforce_inbound_outbound';
            log.Line_Number__c = method;
            log.Notes__c = message;
            
            insert log;
            
            
        } catch (Exception ex) {
            System.debug(ex.getMessage());
        }
        
        
    }
    
}
Is there any way to refactor this code?
I tried to create a list and then use it as an argument for the enqueueJob like this:
if(opptiesToUpdateOnPega.size() > 0){
             
                //List to collect the dvssService that are going to be enqueable-.
                List<DVSSOpptyStageUpdateService> dvssServiceLst = new List<DVSSOpptyStageUpdateService>();
                
                for(Opportunity opp:opptiesToUpdateOnPega){
                    
                    List<SWAP_Tracker__c> swTrack = opp.SWAPS_Tracker__r;
                    
                    system.debug('Oppt info LP>> ' + opp);
                    DateTime dtvar = null;
                    String Casetype='' ;
                    String CaseId='';
            
                    string OpptyStatus = opp.StageName;
                    
                    
                        for(SWAP_Tracker__c swt:swTrack){
                            
                            Casetype =  (DvssCaseTypes.get(swt.Case_Type__c) == null)?'':DvssCaseTypes.get(swt.Case_Type__c);
                            CaseId = (swt.SWAP_Case_ID__c ==null)?'':swt.SWAP_Case_ID__c;
     
                           
                DVSSOpptyStageUpdateService dvssService = new DVSSOpptyStageUpdateService();
                dvssService.Casetype = Casetype;
                dvssService.CaseId = CaseId;
                dvssService.OpptyStatus = OpptyStatus;
                
                dvssServiceLst.add(dvssService);
                
            }  

            
        }
        
        //Taking the enqueueJob out of the for loop-.
        system.enqueueJob(dvssServiceLst);


     }

But then I got an error (I can't remember the error exactly and my dev console is acting up so I can't replicate it) that said something like class List<DVSSOpptyStageUpdateService> needs to implemet queueable (I can't remember the error exactly and my dev console is acting up so I can't replicate it)

Any help with this, thank you very much.
 
Best Answer chosen by Miguel Roa
Shiraz HodaShiraz Hoda
Hi Miguel,

Please do not call queable from for loop. This might be causing issue. Process data in for loop and then pass as parameter to queable.

Regards,
Shiraz

All Answers

Shiraz HodaShiraz Hoda
Hi Miguel,

Please do not call queable from for loop. This might be causing issue. Process data in for loop and then pass as parameter to queable.

Regards,
Shiraz
This was selected as the best answer
SwethaSwetha (Salesforce Developers) 
HI Miguel ,
As suggested in https://salesforce.stackexchange.com/questions/207441/error-too-many-queueable-jobs-added-to-the-queue-2 , keep your batch size low enough that you know evs will contain fewer than 200 records. A more robust fix is to add some logic to check if you should execute synchronously or asynchronously, and only use Queueable in the latter case.

Best practices:
> Ensure that any batch apex referencing @future or Queuable methods are bulkified.
> Avoid @future methods and Queueable methods calling other @future and Queueable methods in a loop.
> Ensure to keep a maximum batch size 2k for batch classes.

Hope this helps!Thanks
Miguel RoaMiguel Roa
How would I go about processing data in for loop and then pass as parameter to queable?
Any idea on how to do this?