Using State in Batch Apex
Batch处理中,根据特定需求,会有在处理中计算数量的业务,例如现在需要计算所有满足条件的Opportunity表total__c的总额。
具体代码如下,
代码语言:javascript复制public with sharing class SummarizeAccountTotal implements Database.Batchable<sObject>{
public final String Query;
public integer Summary;
public SummarizeAccountTotal(String q) {
Query=q;
Summary = 0;
}
public Database.QueryLocator start(Database.BatchableContext BC){
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext BC,List<sObject> scope){
for(Opportunity opportunityItem : (List<Opportunity>)scope) {
system.debug('>>>>>>>>>opportunityItem.total__c>>::' opportunityItem.total__c);
Summary = Integer.valueOf(opportunityItem.total__c) Summary;
system.debug('>>>>>>>>>Summary>>::' Summary);
}
}
public void finish(Database.BatchableContext BC){
}
}
现有4条数据,每条数据的total__c的值是1
执行如下操作,预想结果总额应该是4,但是执行结果却是2。
代码语言:javascript复制String queryS = 'SELECT Id,Name,total__c FROM Opportunity WHERE DeleteFlg__c = true';
SummarizeAccountTotal batchTest = new SummarizeAccountTotal(queryS);
Database.executeBatch(batchTest, 2);
原因分析:
方法【Database.executeBatch】的第二个参数是2,所以分两次执行,每次执行完execute方法之后,Summary变量都会被清空。
改善方法:
只需实现Database.Stateful接口
代码语言:javascript复制public with sharing class SummarizeAccountTotal implements Database.Stateful{
具体代码如下,
代码语言:javascript复制public with sharing class SummarizeAccountTotal implements Database.Batchable<sObject>, Database.Stateful{
public final String Query;
public integer Summary;
public SummarizeAccountTotal(String q) {
Query=q;
Summary = 0;
}
public Database.QueryLocator start(Database.BatchableContext BC){
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext BC,List<sObject> scope){
for(Opportunity opportunityItem : (List<Opportunity>)scope) {
system.debug('>>>>>>>>>opportunityItem.total__c>>::' opportunityItem.total__c);
Summary = Integer.valueOf(opportunityItem.total__c) Summary;
system.debug('>>>>>>>>>Summary>>::' Summary);
}
}
public void finish(Database.BatchableContext BC){
}
}
代码语言:javascript复制String queryS = 'SELECT Id,Name,total__c FROM Opportunity WHERE DeleteFlg__c = true';
SummarizeAccountTotal batchTest = new SummarizeAccountTotal(queryS);
Database.executeBatch(batchTest, 2);