Is there any execution context which uses asynchronous governor limits and allows up to 50 jobs to be queued with System.enqueueJob
in a single transaction, or is Salesforce’s documentation just wrong?
Since API v32.0, the primary documentation for governor limits has stated that the:
"maximum number of Apex jobs added to the queue with System.enqueueJob" is 50 in both synchronous and asynchronous contexts.
I have tested this in every asynchronous context that I’m aware of, and it appears that the true limit on asynchronous use of System.enqueueJob is actually 1.
Test Queueable Used:
public class QueueableTest implements Queueable{
public void execute(QueueableContext context){
System.debug('do stuff');
}
}
Test future method:
@future
public static void futureTest(){
Id jobId1 = System.enqueueJob(new QueueableTest());
Id jobId2 = System.enqueueJob(new QueueableTest());
}
Test batch job (tested start, execute, and finish independently):
public class BatchTest implements Database.Batchable<sObject> {
public Database.QueryLocator start(Database.BatchableContext bc){
Id jobId1 = System.enqueueJob(new QueueableTest());
Id jobId2 = System.enqueueJob(new QueueableTest());
String q = 'SELECT Id FROM Contact LIMIT 1';
return Database.getQueryLocator(q);
}
public void execute(Database.BatchableContext bc, List<Contact> scope){
Id jobId1 = System.enqueueJob(new QueueableTest());
Id jobId2 = System.enqueueJob(new QueueableTest());
}
public void finish(Database.BatchableContext bc){
Id jobId1 = System.enqueueJob(new QueueableTest());
Id jobId2 = System.enqueueJob(new QueueableTest());
}
}
Test from another queueable:
public class QueueableTest2 implements Queueable{
public void execute(QueueableContext context){
Id jobId1 = System.enqueueJob(new QueueableTest());
Id jobId2 = System.enqueueJob(new QueueableTest());
}
}
In all of the above, I get the following error:
FATAL_ERROR System.LimitException: Too many queueable jobs added to the queue: 2
It does appear to be possible to enqueue multiple jobs from a schedulable, like this:
public class SchedulableTest implements Schedulable{
public void execute(SchedulableContext sc){
Id jobId1 = System.enqueueJob(new QueueableTest());
Id jobId2 = System.enqueueJob(new QueueableTest());
}
}
However, it is already established that scheduled apex uses synchronous governor limits.
So what am I missing here? I am not asking why the limit would be 1. I just want to know whether I've misunderstood something or if the documentation is inaccurate.
Best Answer
Yes, the documentation in question is incorrect. You can prove that the
Limits
class does not conform to what is written therein fairly easily:Proving it for batches is a fairly straightforward alteration of the above.
Some pieces of the documentation, however, do touch on this point in a way that properly explains the governor limits involved. They are somewhat lacking in clarity, but you can only execute one job from within a job. Here's one such example:
Also from the same document: