Salesforce Batchable

前言


Salesforce开发语言Apex相对于其他编程语言而言较为简单,所涉及内部并不复杂。基于Apex并没有提供线程的管理和使用、单次Transaction的查询数据限制而实际过程中我们需要大批量的数据去执行特定的操作,Salesforce提供了Batchable接口,通过实现Batchable接口实现批量对数据进行CRUD。那么Batchable有哪些特性呢?

Batch相关

  • Batchable:Interface,实现该接口可进行Batch操作;
  • Stateful:Interface,实现该接口可指定成员变量全局更改和读取;否则变量只能读取初始值;
  • BatchableContext:Interface,批处理作业参数类型(包含批处理作业Id),通常是start()和execute()参数;
  • QueryLocator:数据集装载;
  • executeBatch:Method,Database Namespace指定执行;
  • scheduleBatch:Method, System Namespace指定执行;
  • AllowsCallouts:Interface,实现该接口后可进行CallOut。

Batchable方法


Batchable具有三个方法:
  1. start():返回包含记录的Database.queryLocator或者Iterable,并传递到execute();
    • 使用Database.queryLocator方式,将跨过SOQL的限制,但是最多返回50,000,000数据;
    • 如果是外部数据,则需强制使用Iterable返回。
  2. execute():拿到start()的数据后,开始执行自定义逻辑;
    • 批次顺序是按着搜索到的先后时间决定。但实际搜索时间还有其他因素的限制,故不保障执行顺序。
  3. finish():通常用来作为提醒,例如邮件等方式。
注:Batch是分批执行,因此execute方法一次不会拿到所有检索数据(例如检索1W条,但是每个批次可能只有200)。另各批次执行结果不会相互影响,例如第一批次的失败,不会影响第二批次的运行,同样也不会回滚。

一个简单的例子:
global class BatchTest implements DataBase.Batchable {
    
    global DataBase.QueryLocator start(DataBase.BatchableContext BC) {
        System.debug('----in BatchTest start');
        System.debug('----BatchTest DataBase.BatchableContext'+BC);
        System.debug('----out BatchTest start');
        return DataBase.getQueryLocator('SELECT id FROM Account');
    }
    
    global void execute(DataBase.BatchableContext BC, List scope) {
        System.debug('----in BatchTest execute');
        System.debug('----BatchTest execute DataBase.BatchableContext:'+BC);
        System.debug('----BatchTest execute List'+scope);
        System.debug('----out BatchTest execute');
    }
    
    global void finish(DataBase.BatchableContext BC) {
        System.debug('----in BatchTest finish');
        System.debug('----in BatchTest DataBase.BatchableContext:'+BC);
        System.debug('----out BatchTest finish');
    }
}

调用Batch


调用Batch不可以直接new后使用execute方法(类似JAVA Thread的调用)。调用方法有两种:
  • Database.execute(Batchable batch):返回CronTrigger Id;
  • System.scheduleBatch(Batchable batch,  String name, Integer minutes, [optional value]):返回CronTrigger Id.时间指定多少分钟之后启用,optional指定每批次数量。
得到Batch执行Id后如何查询呢?可通过CronTrigger sObject进行查询,示例:
CronTrigger ct = [SELECT Id, TimesTriggered, NextFireTime FROM CronTrigger WHERE Id = :cronID];
那么如何终止Batch或者取消某一批次呢?可以使用
System.abortJob(BatchId);
System.FlexQueue.moveBeforeJob(jobToMoveId, jobInQueueId);
这两种方式就不展开去叙述了。

限制说明


这里只列出笔者认为重要的:
  • Database.QueryLocator最多返回5000W数据,超过限制会导致该次Job立刻失败;
  • Batch默认每批次是200条数据,可以根据需要进行修改,但是上限为2000;
  • Batch实现AllowCallouts接口后,start/execute/finish每个方法的Callout上限为100;
  • Batch不允许有future方法也不允许由future方法调用。
Batch运行期间状态列表:
  1. Holding:已提交Batch,等待系统资源进行执行;
  2. Queued:进入队列等待执行;
  3. Preparing:已执行start()方法。这个状态随读取数据量不同而持续时间不同;
  4. Processing:执行中;
  5. Aborted:被用户取消;
  6. Completed:执行成功;
  7. Failed:执行期间遇到问题并结束。

心得


Stateful和AllowCallouts不进行代码展示,因其使用非常简单:只需实现接口就可以进行相关的操作,从感觉上而言更像是一个开关,是不是允许你做。Batch的写法相对不是很复杂,在实际过程中常常伴着Schedule进行,但是也可由Trigger、Apex(Generic)进行触发。Trigger触发具有相应的限制,单个Transaction最多允许5个Batch,调用之前应该先进行查询以避免被限制。

参考


https://resources.docs.salesforce.com/208/latest/en-us/sfdc/pdf/salesforce_apex_language_reference.pdf

你可能感兴趣的:(Salesforce,Batch,Salesforce)