我们在日常工作中,很多场景都需要处理数据。apex中一个transaction只能最多10000条数据DML操作,针对大数据量我们会使用batch来进行异步的大数据量处理。batch最多可以操作5000万条数据,它会将数据进行分块,然后对每一块进行处理,如果不设置batch size,默认每一组会有200条数据。我们先以一个例子进行切入。下面的例子时将所有的 Account数据的 Test__c字段设置默认初始值 → default value。
global class RefreshAccountBatch implements Database.Batchable<sObject>, Database.Stateful {
Integer successDataSize = 0;
Integer failedDataSize = 0;
global Database.QueryLocator start(Database.BatchableContext bc) {
String queryStatement = 'SELECT Id,Test__c FROM Account';
return Database.getQueryLocator(queryStatement);
}
global void execute(Database.BatchableContext BC, list<Sobject> scope) {
for(Account accountItem : (List<Account>) scope) {
accountItem.Test__c = 'default value';
}
List<Database.SaveResult> srList = Database.update(scope, false);
for(Database.SaveResult sr : srList) {
if(sr.isSuccess()) {
successDataSize += 1;
} else {
failedDataSize += 1;
}
}
}
global void finish(Database.BatchableContext BC) {
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
email.setPlainTextBody('成功数量' + successDataSize + ';失败数量:' + failedDataSize);
email.setSubject('数据清洗结果');
email.setToAddresses(new List<String>{'your email set here'});
Messaging.sendEmail(new List<Messaging.SingleEmailMessage>{email});
}
}
上面的demo中,我们看到此类实现了Database.Batchable<sObject>接口,所有的batch均需要实现此接口。除此以外,batch类还会需要实现三个封装的方法:
除了这些信息以外,我们看到接口还实现了 Database.Stateful接口。举个例子,当1000条数据处理,batch size设置200情况下,会有5组数据块用来执行这些全部数据,这些数据执行是毫无关系的,每一组块都执行各自的,执行以后,相关的全局变量也会重置到初始状态。有一些场景需要将这些块的数据关联起来,即全局变量不会因为当前的数据块执行完成以后重置,我们便可以实现 Database.Stateful接口。上方demo中统计总共的成功和失败数量,就是其中一个使用场景。除此以外,针对callout等操作,batch都需要实现相关的接口以及一些处理,详情查看文档中的介绍。
调用batch:使用 Database.executeBatch方法调用,设置每一组数据块的数据量即可,batch size最多可以设置到1000。
RefreshAccountBatch accountBatch = new RefreshAccountBatch();
Database.executeBatch(accountBatch,10);
结果显示:
参考文档: