0

I have the following trigger:

trigger CaseMainTrigger_tgr on Case (before update, after insert, after update, after delete) 
{
    if(Trigger.isBefore){
        if(Trigger.isUpdate){
           
           CaseMethods_cls.manageUpdatedCases(Trigger.oldMap, Trigger.newMap);
           CaseMethods_cls.createCaseComments(Trigger.oldMap, Trigger.newMap);
           CaseMethods_cls.updateDate(Trigger.oldMap, Trigger.newMap);
            
            Map<Id,Schema.Case> mapOldCases = Trigger.oldMap;
            Map<Id,Schema.Case> mapNewCases = Trigger.newMap;
            for(Id iterator:mapOldCases.keySet()){
    
                if(mapOldCases.get(iterator).ComplainType__c == 'Reportes' && (mapOldCases.get(iterator).OtherComplainceStatus__c != mapNewCases.get(iterator).OtherComplainceStatus__c)){
                  SMS smsAsync = new SMS();
                          smsAsync.old = Trigger.oldMap;
                          smsAsync.news = Trigger.newMap;
                  System.enqueueJob(smsAsync);  
                } else {
                    break;
                }
            }
        }
    }
}

And a process like this:

public class SMS implements Queueable, Database.AllowsCallouts{

    public  Map<Id,Schema.Case> old {get;set;}
    public  Map<Id,Schema.Case> news {get;set;}


    public void execute(QueueableContext context) {        
        if(!Test.isRunningTest()){ 
            ValidateActivate.sendSMSNotification_Queja(old,news);
        }        
    }    
}

I understand that the error is due to "too many jobs in queue" and that it is a transaction error. The problem is how can I correct my code to skip or replace the process.

8
  • !Bienvenidos a SFSE! Este sitio solo esta en Ingles. Esta vez, traducimos este pregunta para tu.
    – Derek F
    Commented Jul 18, 2023 at 18:12
  • I understand, thank you very much Commented Jul 18, 2023 at 18:13
  • You may find the answer to this question of help. Alternatively read this article.
    – Phil W
    Commented Jul 18, 2023 at 19:15
  • @PhilW I'm sorry, I still can't find the solution :( Commented Jul 18, 2023 at 19:30
  • How would the correct code look? sorry for my bad english Commented Jul 18, 2023 at 20:09

1 Answer 1

0

You can add up to 50 jobs to the queue with System.enqueueJob in a single transaction. In asynchronous transactions (for example, from a batch Apex job), you can add only one job to the queue with System.enqueueJob. To check how many queueable jobs have been added in one transaction, call Limits.getQueueableJobs().

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_queueing_jobs.htm

To avoid enqueuing duplicate jobs for the same case, you can try using a set to bulkify your code in this scenario as follows. Further if the problem persists, you can consider frameworks like https://gist.github.com/tshevchuk/c6568601912843c50f97d965d4ce09e2

trigger CaseMainTrigger_tgr on Case (before update, after insert, after update, after delete) {
if (Trigger.isBefore) {
    if (Trigger.isUpdate) {
        CaseMethods_cls.manageUpdatedCases(Trigger.oldMap, Trigger.newMap);
        CaseMethods_cls.createCaseComments(Trigger.oldMap, Trigger.newMap);
        CaseMethods_cls.updateDate(Trigger.oldMap, Trigger.newMap);

        Set<Id> caseIdsToSendSMS = new Set<Id>();
        for (Case updatedCase : Trigger.new) {
            Case oldCase = Trigger.oldMap.get(updatedCase.Id);
            if (oldCase.ComplainType__c == 'Reportes' && oldCase.OtherComplainceStatus__c != updatedCase.OtherComplainceStatus__c) {
                caseIdsToSendSMS.add(updatedCase.Id);
            }
        }

        if (!caseIdsToSendSMS.isEmpty()) {
            List<SMS> smsJobs = new List<SMS>();
            for (Id caseId : caseIdsToSendSMS) {
                SMS smsAsync = new SMS();
                smsAsync.old = Trigger.oldMap;
                smsAsync.news = Trigger.newMap;
                smsAsync.caseId = caseId;
                smsJobs.add(smsAsync);
            }
            for (SMS smsJob : smsJobs) {
                System.enqueueJob(smsJob);
            }
        }
    }
}
6
  • Thank you very much for the answer, but in the second part of the Queueable, would everything be the same? :) Commented Jul 20, 2023 at 16:23
  • I replicated the code, and it generates an error in the caseId class, I omitted it, when I run the code I get an error: Trigger.CaseMainTrigger_tgr: line 48, column 1 17:53:19.732 (23732331825)|CUMULATIVE_LIMIT_USAGE 17:53:19.732 (23732331825)|LIMIT_USAGE_FOR_NS|(default)| -- And Code: smsAsync.news = Trigger.newMap; smsAsync.caseId = caseId; smsJobs.add(smsAsync); } 48 for (SMS smsJob : smsJobs) { System.enqueueJob(smsJob); Commented Jul 21, 2023 at 0:07
  • Trigger.CaseMainTrigger_tgr: line 48, column 1 17:53:19.732 (23732331825)|CUMULATIVE_LIMIT_USAGE 17:53:19.732 (23732331825)|LIMIT_US EDAD_PARA_NS|(predeterminado)| Commented Jul 21, 2023 at 0:55
  • @ Vijaya Kapadam ->line 48---> for (SMS smsJob : smsJobs) ---- pls help.. Commented Jul 21, 2023 at 15:18
  • The error (23732331825)|CUMULATIVE_LIMIT_USAGE is raised when you've exceeded one of the governor limits in Apex. It's not exactly clear which limit is being exceeded based on the provided information. Also, chaining will not solve the problem if you're hitting a governor limit in a single execution context. I feel you should consider using batch Apex. Commented Jul 22, 2023 at 1:13

You must log in to answer this question.

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