This as an example will prevent anyone other than System Administrators to update any Notes
trigger UpdateNotes on Note (before update) {
public class myException extends Exception{}
Profile profileID = [Select id From Profile where Name Like 'System Administrator' LIMIT 1];
list<User> thisUser = [Select id,ProfileID From User where ProfileID !=: profileID.id and IsActive=true and id =:userinfo.getUserId() limit 1];
if (thisUser.size() > 0){
//not sys admin
throw new myException('Cannot update');
}
}
Search
Thursday, 1 September 2011
Batch Apex Processing
This is based on a speech I made to the Salesforce London Group.
This is a brief introduction to batch processing
This is a brief introduction to batch processing
Batch Requirements
Every batch class requires 4 things. To implement Database.Batchable<sObject>, have a start(),execute() and finish() methods.
global class UpdatetFields implements Database.Batchable<sObject>{
global Database.QueryLocator start(Database.BatchableContext BC){
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext BC,
List<sObject> scope){
}
global void finish(Database.BatchableContext BC){
}
}
Governor Limits
In total 50 million records can be processed by a batch class and 5 batches can be run simultaneously, giving a total of 250 million records that can be processed at 1 time.
Remember batch classes still need to adhere to governor limits, so if any soql’s are performed do remember that these soql’s need to adhere to governor limits
The following is likely to break governor limits because List<sObject> scope is likely to contain more than 200 records and so the soql in bold will run 200 times per batch that is processed.
global void execute(Database.BatchableContext BC,
List<sObject> scope){
ID thisCustID;
List<Customers__c> allsubs;
for (SObject sub: scope){
thisCustID = (ID)sub.get(‘Customers__c');
allsubs = [Select Name From Customers__c where id =: thisCustID];
}
}
Types of Batch Classes
Using Database.QueryLocator this passes an list of SObjects. This is the most common type used in batch processing. Or you can use Iterable which allows you to step through the records more easily, which is mainly used for more complex soql’s such as nested soql’s.
global Database.QueryLocator start(Database.BatchableContext BC){
return Database.getQueryLocator(query);
}
Or
global Iterable start(Database.BatchableContext BC){
return Database.getQueryLocator(query);
}
And
If your batch performs a callout you must implement Database.AllowsCallouts
global class SearchAndReplace implements Database.Batchable<sObject>,
Database.AllowsCallouts{
}
And
If you specify Database.Stateful in the class definition, you can maintain state across these transactions. This is can be used for example if you want to make some kind of summary, or total of the records processed, or could be used to summarise all the successful or failure transactions produced etc.
global class UpdatetFields implements Database.Batchable<sObject>, Database.Stateful{
}
Ensure Batches Don’t Try To Update The Same Records
Use AsyncApexJob to query when a batch has completed processing so you can run the next batch
ID batchprocessid = Database.executeBatch(reassign);
AsyncApexJob aaj = [SELECT Id, Status, JobItemsProcessed, TotalJobItems, NumberOfErrors
FROM AsyncApexJob WHERE ID =: batchprocessid ];
If (aaj.Status == ‘Completed’){
//run next batch
}
Else { }
Custom Schedule Classes
If you ever have to shceduled a class but provide a specific custom shcedule plan run a bit of code in the System Log, similar to
string CRON_EXP = '0 30 * ? * MON-FRI';
string jobid=System.Schedule('<<any name>>',CRON_EXP, new <<name of class>>());
This will run the class every 30 mins passed the hour from Mon-Fri
This will run the class every 30 mins passed the hour from Mon-Fri
Changing the 1st line with
CRON_EXP = '0 0 * ? * MON-FRI';
will run the class on the hour
More info for specific customisation at http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_system.htm
Subscribe to:
Posts (Atom)