Apex Scheduler (Schedule job)


  1. You can only have 100 scheduled Apex jobs at one time.
  2. If there are one or more active scheduled jobs for an Apex class, you cannot update the class or any classes referenced by this class through the Salesforce user interface. However, you can enable deployments to update the class with active scheduled jobs by using the Metadata API (for example, when using the Force.com IDE). See “Deployment Connections for Change Sets” in the Salesforce Help.
  3. The Schedulable interface contains one method that must be implemented, execute.   global void execute(SchedulableContext sc){}
  4. The maximum number of scheduled Apex executions per a 24-hour period is 250,000 or the number of user licenses in your organization multiplied by 200, whichever is greater. This limit is for your entire organization and is shared with all asynchronous Apex: Batch Apex, Queueable Apex, scheduled Apex, and future methods. The licenses that count toward this limit are full Salesforce user licenses or Force.com App Subscription user licenses. Chatter Free, Chatter customer users, Customer Portal User, and partner portal User licenses aren’t included.
  5. Synchronous Web service callouts are not supported from scheduled Apex. To be able to make callouts, make an asynchronous callout by placing the callout in a method annotated with @future(callout=true) and call this method from scheduled Apex. However, if your scheduled Apex executes a batch job, callouts are supported from the batch class.
  6. Apex jobs scheduled to run during a Salesforce service maintenance downtime will be scheduled to run after the service comes back up, when system resources become available. If a scheduled Apex job was running when downtime occurred, the job is rolled back and scheduled again after the service comes back up. Note that after major service upgrades, there might be longer delays than usual for starting scheduled Apex jobs because of system usage spikes.

Schedule asynch Job

Asynchronous Apex Best Practice and limits

Limits:

  1. You can only have five queued or active batch jobs at one time.you can evaluate your current count by viewing the Scheduled Jobs page in Salesforce or programmatically using SOAP API to query the AsyncApexJob object.
  2. In Batch Apex If you use an iterable, the governor limit for the total number of records retrieved by SOQL queries is still enforced.
  3. When you call System.scheduleBatch, Salesforce schedules the job for execution at the specified time. Actual execution occurs at or after that time, depending on service availability.
  4. The scheduler runs as system—all classes are executed, whether or not the user has permission to execute the class.
  5. When the job’s schedule is triggered, the system queues the batch job for processing. If Apex flex queue is enabled in your org, the batch job is added at the end of the flex queue. 
  6. All scheduled Apex limits apply for batch jobs scheduled using System.scheduleBatch. After the batch job is queued (with a status of Holding or Queued), all batch job limits apply and the job no longer counts toward scheduled Apex limits.
  7. To exclude accounts or invoices that were deleted but are still in the Recycle Bin, include isDeleted=false in the SOQL query WHERE clause, as shown in these modified samples.
  8. Up to 5 batch jobs can be queued or active concurrently.
  9. Up to 100 Holding batch jobs can be held in the Apex flex queue.
  10. In a running test, you can submit a maximum of 5 batch jobs.
  11. The maximum number of batch Apex method executions per 24-hour period is 250,000, or the number of user licenses in your org multiplied by 200—whichever is greater. Method executions include executions of the start,execute, and finish methods. This limit is for your entire organization and is shared with all asynchronous Apex: Batch Apex, Queueable Apex, scheduled Apex, and future methods. The licenses that count toward this limit are full Salesforce user licenses or Force.com App Subscription user licenses. Chatter Free, Chatter customer users, Customer Portal User, and partner portal User licenses aren’t included.
  12. The batch Apex start method can have up to 15 query cursors open at a time per user. The batch Apex execute and finish methods each have a limit of five open query cursors per user.
  13. A maximum of 50 million records can be returned in the Database.QueryLocator object. If more than 50 million records are returned, the batch job is immediately terminated and marked as Failed.
  14. If the start method of the batch class returns a QueryLocator, the optional scope parameter of Database.executeBatchcan have a maximum value of 2,000. If set to a higher value, Salesforce chunks the records returned by the QueryLocator into smaller batches of up to 2,000 records. If the start method of the batch class returns an iterable, the scope parameter value has no upper limit. However, if you use a high number, you can run into other limits.
  15. If no size is specified with the optional scope parameter of Database.executeBatch, Salesforce chunks the records returned by the start method into batches of 200. The system then passes each batch to the execute method. Apex governor limits are reset for each execution of execute.
  16. The startexecute, and finish methods can implement up to 10 callouts each.
  17. Only one batch Apex job's start method can run at a time in an organization. Batch jobs that haven’t started yet remain in the queue until they're started. Note that this limit doesn’t cause any batch job to fail and execute methods of batch Apex jobs still run in parallel if more than one job is running.
Best Practice:
  1. Use extreme care if you are planning to invoke a batch job from a trigger. You must be able to guarantee that the trigger will not add more batch jobs than the limit. In particular, consider API bulk updates, import wizards, mass record changes through the user interface, and all cases where more than one record can be updated at a time.
  2. You can use the System.scheduleBatch method to schedule a batch job to run once at a future time.
  3. Use the System.Test.enqueueBatchJobs and System.Test.getFlexQueueOrder methods to enqueue and reorder no-operation jobs within the contexts of tests.
  4. When you call Database.executeBatch, Salesforce only places the job in the queue. Actual execution can be delayed based on service availability.
  5. When testing your batch Apex, you can test only one execution of the execute method. Use the scope parameter of the executeBatch method to limit the number of records passed into the execute method to ensure that you aren’t running into governor limits.
  6. The executeBatch method starts an asynchronous process. When you test batch Apex, make certain that the asynchronously processed batch job is finished before testing against the results. Use the Test methods startTest andstopTest around the executeBatch method to ensure that it finishes before continuing your test.
  7. Use Database.Stateful with the class definition if you want to share instance member variables or data across job transactions. Otherwise, all member variables are reset to their initial state at the start of each transaction.
  8. Methods declared as future aren’t allowed in classes that implement the Database.Batchable interface.
  9. Methods declared as future can’t be called from a batch Apex class.
  10. When a batch Apex job is run, email notifications are sent to the user who submitted the batch job. If the code is included in a managed package and the subscribing org is running the batch job, notifications are sent to the recipient listed in the Apex Exception Notification Recipient field.
  11. Each method execution uses the standard governor limits anonymous block, Visualforce controller, or WSDL method.
  12. Each batch Apex invocation creates an AsyncApexJob record. To construct a SOQL query to retrieve the job’s status, number of errors, progress, and submitter, use the AsyncApexJob record’s ID. For more information about theAsyncApexJob object, see AsyncApexJob in the Object Reference for Salesforce and Force.com.
  13. For each 10,000 AsyncApexJob records, Apex creates an AsyncApexJob record of type BatchApexWorker for internal use. When querying for all AsyncApexJob records, we recommend that you filter out records of type BatchApexWorker using the JobType field. Otherwise, the query returns one more record for every 10,000 AsyncApexJob records. For more information about the AsyncApexJob object, see AsyncApexJob in the Object Reference for Salesforce and Force.com.
  14. All methods in the class must be defined as global or public.
  15. For a sharing recalculation, we recommend that the execute method delete and then re-create all Apex managed sharing for the records in the batch. This process ensures that sharing is accurate and complete.
  16. Batch jobs queued before a Salesforce service maintenance downtime remain in the queue. After service downtime ends and when system resources become available, the queued batch jobs are executed. If a batch job was running when downtime occurred, the batch execution is rolled back and restarted after the service comes back up.
  17. Minimize the number of batches, if possible. Salesforce uses a queue-based framework to handle asynchronous processes from such sources as future methods and batch Apex. This queue is used to balance request workload across organizations. If more than 2,000 unprocessed requests from a single organization are in the queue, any additional requests from the same organization will be delayed while the queue handles requests from other organizations.
  18. Ensure that batch jobs execute as fast as possible. To ensure fast execution of batch jobs, minimize Web service callout times and tune queries used in your batch Apex code. The longer the batch job executes, the more likely other queued jobs are delayed when many jobs are in the queue.

Holding Batch Jobs in the Apex Flex Queue


  1. With the Apex flex queue, you can submit up to 100 batch jobs.
  2. The outcome of Database.executeBatch is as follows.
    1. The batch job is placed in the Apex flex queue, and its status is set to Holding.
    2. If the Apex flex queue has the maximum number of 100 jobs, Database.executeBatch throws a LimitException and doesn’t add the job to the queue.
  3. If your org doesn’t have Apex flex queue enabled, Database.executeBatch adds the batch job to the batch job queue with the Queued status. If the concurrent limit of queued or active batch job has been reached, a LimitException is thrown, and the job isn’t queued.
Reordering Jobs in the Apex Flex Queue:

While submitted jobs have a status of Holding, you can reorder them in the Salesforce user interface to control which batch jobs are processed first. To do so, from Setup, enter Apex Flex Queue in the Quick Find box, then select Apex Flex Queue.
Alternatively, you can use Apex methods to reorder batch jobs in the flex queue. To move a job to a new position, call one of the System.FlexQueue methods. Pass the method the job ID and, if applicable, the ID of the job next to the moved job’s new position. For example:
1Boolean isSuccess = System.FlexQueue.moveBeforeJob(jobToMoveId, jobInQueueId);
You can reorder jobs in the Apex flex queue to prioritize jobs. For example, you can move a batch job up to the first position in the holding queue to be processed first when resources become available. Otherwise, jobs are processed “first-in, first-out”—in the order in which they’re submitted.
When system resources become available, the system picks up the next job from the top of the Apex flex queue and moves it to the batch job queue. The system can process up to five queued or active jobs simultaneously for each organization. The status of these moved jobs changes from Holding to Queued. Queued jobs get executed when the system is ready to process new jobs. You can monitor queued jobs on the Apex Jobs page.

Chaining Batch Jobs



Chaining Batch Jobs

Starting with API version 26.0, you can start another batch job from an existing batch job to chain jobs together. Chain a batch job to start a job after another one finishes and when your job requires batch processing, such as when processing large data volumes. Otherwise, if batch processing isn’t needed, consider using Queueable Apex.
You can chain a batch job by calling Database.executeBatch or System.scheduleBatch from the finish method of the current batch class. The new batch job will start after the current batch job finishes.
For previous API versions, you can’t call Database.executeBatch or System.scheduleBatch from any batch Apex method. The version that’s used is the version of the running batch class that starts or schedules another batch job. If the finishmethod in the running batch class calls a method in a helper class to start the batch job, the API version of the helper class doesn’t matter.

Batch Apex(Apex Batch Class)


  1. To use batch Apex, write an Apex class that implements the Salesforce-provided interface Database.Batchable and then invoke the class programmatically.
  2. The Database.Batchable interface contains three methods that must be implemented.
    1. start method:  
      1. global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext ***bc***) {}
    2. execute method: 
      1. global void execute(Database.BatchableContext ***BC***, list<P>){}
      2. To do the required processing for each chunk of data, use the execute method. This method is called for each batch of records that you pass to it.
      3. This method takes the following:
        1. A reference to the Database.BatchableContext object.
        2. A list of sObjects, such as List<sObject>, or a list of parameterized types. If you are using a Database.QueryLocator, use the returned list.Batches of records tend to execute in the order in which they’re received from the start method. However, the order in which batches of records execute depends on various factors. The order of execution isn’t guaranteed.
    3. finish method:
      1. To send confirmation emails or execute post-processing operations, use the finish method. This method is called after all batches are processed.
  3. All the methods in the Database.Batchable interface require a reference to a Database.BatchableContext object.
  4. getJobID():
    1. Returns the ID of the AsyncApexJob object associated with this batch job as a string. Use this method to track the progress of records in the batch job. You can also use this ID with the System.abortJob method.
    2. global void finish(Database.BatchableContext BC){
        AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
            TotalJobItems, CreatedBy.Email
            FROM AsyncApexJob WHERE Id =
            :BC.getJobId()];}
  5. The Database.executeBatch method takes two parameters:
    • An instance of a class that implements the Database.Batchable interface.
    • An optional parameter scope. This parameter specifies the number of records to pass into the execute method. Use this parameter when you have many operations for each record being passed in and are running into governor limits. By limiting the number of records, you are limiting the operations per transaction. This value must be greater than zero. If the start method of the batch class returns a QueryLocator, the optional scope parameter of Database.executeBatch can have a maximum value of 2,000. If set to a higher value, Salesforce chunks the records returned by the QueryLocator into smaller batches of up to 2,000 records. If the start method of the batch class returns an iterable, the scope parameter value has no upper limit. However, if you use a high number, you can run into other limits.
  6. The Database.executeBatch method returns the ID of the AsyncApexJob object, which you can use to track the progress of the job.

Batch Job Statuses

The following table lists all possible statuses for a batch job along with a description of each.
StatusDescription
HoldingJob has been submitted and is held in the Apex flex queue until system resources become available to queue the job for processing.
QueuedJob is awaiting execution.
PreparingThe start method of the job has been invoked. This status can last a few minutes depending on the size of the batch of records.
ProcessingJob is being processed.
AbortedJob aborted by a user.
CompletedJob completed with or without failures.
FailedJob experienced a system failure.

Using the System.scheduleBatch Method

You can use the System.scheduleBatch method to schedule a batch job to run once at a future time.
The System.scheduleBatch method takes the following parameters.
  • An instance of a class that implements the Database.Batchable interface.
  • The job name.
  • The time interval, in minutes, after which the job starts executing.
  • An optional scope value. This parameter specifies the number of records to pass into the execute method. Use this parameter when you have many operations for each record being passed in and are running into governor limits. By limiting the number of records, you are limiting the operations per transaction. This value must be greater than zero. If the start method returns a QueryLocator, the optional scope parameter of System.scheduleBatch can have a maximum value of 2,000. If set to a higher value, Salesforce chunks the records returned by the QueryLocator into smaller batches of up to 2,000 records. If the start method returns an iterable, the scope parameter value has no upper limit. However, if you use a high number, you can run into other limits.
  • The System.scheduleBatch method returns the scheduled job ID (CronTrigger ID).

Using Callouts in Batch Apex

To use a callout in batch Apex, specify Database.AllowsCallouts in the class definition. For example:
1global class SearchAndReplace implements Database.Batchable<sObject>,
2   Database.AllowsCallouts{
3}

Counters