如何在Apex批处理作业中保持静态变量的状态

时间:2018-03-04 18:16:47

标签: salesforce apex-code apex force.com

我必须一个接一个地执行许多(超过10个)批处理作业,以确保它不超过调控器限制。

我想实现类似下面的内容,但它不起作用,因为stateful doesn't work for static

public class MyBatch implements Database.Batchable<SObject>, 
                               Database.Stateful
{
  private String a;
  private Static List<String> aList = new List<String>();
  private static Integer currentIndex = 0;

  static
  {
      aList = getAllAList();
  }

  public MyBatch(String a)
  {
     this.a = a;
  }

  public Database.QueryLocator start(Database.BatchableContext bc)
  {
      return Database.getQueryLocator('some query which may get 30k 
                                           records');
  }

  public void execute(Database.BatchableContext BC, List<sObject> 
                            recordList)
  {
      System.debug('execute');
      System.debug(recordList);
  }

  public void finish(Database.BatchableContext BC)
  {
      System.debug('finish');
      //do I have another A.
      if(currentIndex < aList.size())
      {
        cuurentIndex++;
        System.debug('Starting another batch: '+ anotherA);
        Database.executeBatch(new MyBatch(aList.get(currentIndex));
      }
  }
}

所以在finish方法中,currentIndex总是为零,因此它总是在aList中得到第一个值。

我也尝试过来自其他类的一些其他静态变量,但这也不起作用。

有没有办法在不使用数据库事务的情况下实现这个目标?

2 个答案:

答案 0 :(得分:0)

您无法像这样调用它,因为在(所有)批次结束时只调用一次finish方法。 所以start和execute方法很重要。根据batchsize,查询结果将分成x个块,execute方法将完成剩下的工作。 并且因为一旦你的索引最多增加一次就会调用finish方法。如果在excute方法中递增它,它将在每次新批次(块)运行时递增

答案 1 :(得分:0)

我已经通过在批次类中保持currentIndex并在调用下一批时传递它来实现。

public class MyBatch implements Database.Batchable<SObject>, 
                           Database.Stateful
{
  private List<String> aList = null;
  private Integer currentIndex;


  public MyBatch(List<String> aList, Integer index)
  {
     this.aList = aList;
     this.index = index;
  }

  public Database.QueryLocator start(Database.BatchableContext bc)
  {
      return Database.getQueryLocator('some query which may get 30k 
                                           records');
  }

  public void execute(Database.BatchableContext BC, List<sObject> 
                            recordList)
  {
      System.debug('execute');
      System.debug(recordList);
  }

  public void finish(Database.BatchableContext BC)
  {
      System.debug('finish');
      //do I have another A.
      currentIndex++;
      if(currentIndex < aList.size())
      {
        System.debug('Starting another batch: ');
        Database.executeBatch(new MyBatch(aList, currentIndex);
      }
  }
}

因此,这里的想法是将批量索引作为私有成员而不是静态成员,并检查大小是否超过然后触发下一批。