Batch Apex & Schedule Apex
Batch
Apex is exposed as an interface that must be implemented by the developer.
Batch jobs can be programmatically invoked at runtime using Apex.
To
use batch Apex, you must write an Apex class that implements the
Salesforce-provided interface Database.Batchable, and then invoke the class programmatically. To monitor or
stop the execution of the batch Apex job, from Setup, click Monitoring > Apex Jobs or Jobs > Apex
Jobs..
Implementing the Database.Batchable Interface
The
Database.Batchable interface
contains three methods that must be implemented.
v Start
Method
v Excute
Method
v Finish
Method
Start
Method:
The
start method
is called at the beginning of a batch Apex job. Use the start method
to collect the records or objects to be passed to the interface method execute. This method returns either a Database.QueryLocator object
or an iterable that contains the
records or objects being passed into the job.
Syntax:
global (Database.QueryLocator | Iterable<sObject>)
start(Database.BatchableContext bc)
{
// Fetch
records here
}
Excute
Method:
The
execute method
is called for each batch of records passed to the method. Use this method to do
all required processing for each chunk of data.
This
method takes the following:
v A reference to the Database.BatchableContext object.
v A list of sObjects, such as List<sObject>,
or a list of parameterized types. If you are using a
Database.QueryLocator, the returned list should be used.
Syntax:
global void execute(Database.BatchableContext
BC, list<P>){
// perform dml operations here
}
Finish Method:
The finish method
is called after all batches are processed. Use this method to send confirmation
emails or execute post-processing operations…
Syntax:
global void finish(Database.BatchableContext
BC){
//send
confirmationmails or messages
}
What
is Database.BatchableContext?
Represents the parameter type of a batch
job method and contains the batch job ID. This interface is implemented internally by Apex.
Returns the ID of the AsyncApexJob object
associated with this batch job as a string. Use this method to track getJobID. ID the progress of records in
the batch job. You can also use this ID with the System.abortJob method.
How we will find errors in
the Batch Job?
By Using Soql:
AsyncApexJob a = [SELECT Id, Status, NumberOfErrors,
JobItemsProcessed,TotalJobItems, CreatedBy.Email
FROM AsyncApexJob WHERE Id =::BC.getJobId()];
Difference between Database.QueryLocator and iterable ?
Use the Database.QueryLocator object
when you are using a simple query (SELECT)
to generate the scope of objects used in the batch job. If you use a
querylocator object, the governor limit for the total number of records
retrieved by SOQL queries is bypassed. For example, a batch Apex job for the
Account object can return a QueryLocator
for all account records (up to 50 million records) in an
organization.
Use the iterable
when you need to create a complex scope for the batch job. You can also use the
iterable to create your own custom process for iterating through the list.
Important: If you use
an iterable, the governor limit for the total number of records retrieved by
SOQL queries is still enforced.here we will Retrive maximum 50,000 records only.
Database.executeBatch
Method
The
Database.executeBatch method
takes two parameters:
• An
instance of a class that implements the Database.Batchable interface.
• The
Database.executeBatch method
takes an optional parameter scope. This parameter specifies the number of records that should be
passed 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 thereby 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 minimum value of 200 and maximum value of 2000.
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 should start executing
Apex
Scheduler
To invoke Apex classes to run at specific
times, first implement the Schedulable
interface for the class, then specify the
schedule using either the Schedule Apex page in the Salesforce user interface,
or the System.schedule method.
You
can evaluate your current count by viewing the Scheduled Jobs page in
Salesforce and creating a custom view with a type filter equal to “Scheduled
Apex”. You can also programmatically query the CronTrigger and CronJobDetail
objects to get the count of Apex scheduled jobs. You can only have 100 scheduled Apex jobs at one time.
The Schedulable interface contains one method
that must be implemented, execute.
global void execute(SchedulableContext
sc){
}
Scheduleapex
example:
global
class scheduleaccount1 implements schedulable{
global void execute(SchedulableContext sc){
account a = new account();
a.name = 'prasaddarling';
insert a;
}
}
Test class for scheduleapex:
Programitacally we will schedule like this
@isTest
public class testschedule {
public static testmethod void testschedule(){
scheduleaccount1 scc = new scheduleaccount1()
String crexp = '0 0 5 11 9 ? '; String jobid = system.schedule('varam', crexp, scc);
}
}
Declarative way we will schedule like this:
Schedule an Apex class that implements the 'Schedulable' interface to be automatically executed on a weekly or monthly interval.
|
Simple Example:
global
class batchClass implements Database.batchable<sobject>{
string
query = 'select name,rating,type from account';
global
Database.querylocator start (Database.Batchablecontext bc){
return Database.getquerylocator(query);
}
global void execute(Database.BatchableContext
BC, List<Account> acc) {
for(Account a : acc)
{
if(a.type=='prospect'){
a.rating = 'hot';
}
}
update acc;
}
global void
finish(Database.BatchableContext BC) {
}
}
We
will excute this in Developer console
batchClass
b = new batchClass ();
database.executeBatch(b);
Test
class for Above class:
@isTest
public
class TestBatchclass {
public static testmethod void main(){
String query = 'select name,rating,type
from account';
for(integer i=0;i<=5;i++){
account a=new account(name='lover'+i,rating='cold',type='prospect');
insert a;
}
Test.startTest();
batchClass b = new batchClass();
database.executeBatch(b);
test.stopTest();
integer i=[select count() from
account];
System.assertEquals(i,6);
}
}
How to schedule batchapex:
global
class batchclass schedule implements schedulable{
global void execute(SchedulableContext sc){
batchClass bc = new batchClass ();
database.executebatch(bc);
}
}
Batch Apex Governor Limits
Keep in mind the following governor limits for batch Apex:
• Up to five queued or active batch jobs are allowed
for Apex.
• The maximum number of batch Apex method executions
per a 24-hour period is 250,000 or the number of user licenses
in your organization multiplied by 200, whichever is greater.
Method executions include executions of the start, execute,
and finish methods. This is an
organization-wide limit and is shared with all other asynchronous 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.
• 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 different limit of 5 open
query cursors per user.
• 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.
• 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 very high number,
you may run into other limits.
• 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,
and then passes each batch to the execute method. Apex governor
limits are reset for each execution of execute.
• The start, execute, and finish methods can implement up to 10 callouts each.
• 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.
Batch Apex Best Practices
• 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 five that are allowed. 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.
• When you call Database.executeBatch, Salesforce only places the job in the queue. Actual execution
may be delayed
based on service availability.
• When testing your batch Apex, you can test only
one execution of the execute method. You can 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.
• The executeBatch method starts an asynchronous process. This means that when you
test batch Apex, you must make
certain that the batch job is finished before testing against the
results. Use the Test methods startTest and stopTest
around the executeBatch method
to ensure it finishes before continuing your test.
• 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.
• Methods declared as future aren't allowed in classes that implement the Database.Batchable interface.
• Methods declared as future can't be called from a batch Apex class.
• Starting with Apex saved using Salesforce.com API
version 26.0, you can call Database.executeBatch or
System.scheduleBatch from the finish method. This enables you to start or schedule a new batch job when
the
current batch job finishes. For previous versions, you can’t call Database.executeBatch or System.scheduleBatch
from any batch Apex method. Note that the version used is the
version of the running batch class that starts or schedules
another batch job. If the finish method in the running batch class calls a method in a helper class
to start the batch job,
the Salesforce.com API version of the helper class doesn’t matter.
• You cannot use the getContent and getContentAsPDF PageReference methods in a batch job.
• When a batch Apex job is run, email notifications
are sent either to the user who submitted the batch job, or, if the code
is included in a managed package and the subscribing organization
is running the batch job, the email is sent to the recipient
listed in the Apex
Exception Notification Recipient field.
• Each method execution uses the standard governor
limits anonymous block, Visualforce controller, or WSDL method.
• Each batch Apex invocation creates an AsyncApexJob record. Use the ID of this record to construct a
SOQL query to
retrieve the job’s status, number of errors, progress, and
submitter. For more information about the AsyncApexJob object,
see AsyncApexJob in the Object Reference for Salesforce and Force.com.
• For each 10,000 AsyncApexJob records, Apex creates one additional 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 will return 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.
• All methods in the class must be defined as global or public.
• 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 ensures the sharing is accurate
and complete.
Apex Scheduler Limits
• You can only have 100 scheduled Apex jobs at one
time. You can evaluate your current count by viewing the Scheduled
Jobs page in Salesforce and creating a custom view with a type
filter equal to “Scheduled Apex”. You can also
programmatically query the CronTrigger and CronJobDetail objects
to get the count of Apex scheduled jobs.
• 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 is
an organization-wide limit and is shared with all other
asynchronous Apex: batch 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.
Apex Scheduler Best Practices
• Salesforce schedules the class for execution at
the specified time. Actual execution may be delayed based on service
availability.
• Use extreme care if you’re planning to schedule a
class from a trigger. You must be able to guarantee that the trigger won’t
add more scheduled classes than the 100 that are allowed. 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.
Invoking Apex Apex Scheduler
• Though it's possible to do additional processing
in the execute method, we recommend that all
processing take place in
a separate class.
• You can't use the getContent and getContentAsPDF PageReference methods in scheduled Apex.
• 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.
See Using Batch Apex.
• 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.
No comments:
Post a Comment