异步

异步处理

  • Future Annotation
  • 批处理任务
  • 队列,实现 Queueable 接口
  • 定时任务,schedule

Future Annotation

  • Future 方法必须是静态方法,并且只能返回 void
  • 参数只能是原始数据类型或者原始数据类型的数组或集合
  • Future 方法不能调用另外一个 Future 方法
  • 每24小时最多可调用25万个 Future 方法,或者您组织中的用户许可数量乘以200,以较大者为准
  • (callout=true) 允许调用外部请求

global class FutureClass
{
    @future(callout=true)
    public static void myFutureMethod()
    {   
         // Do Sth
    }
}

批处理任务

批处理


// Database.Stateful 记录上下文中的数据
// Database.AllowsCallouts 允许调用外部请求
global without sharing class MyBatchClass implements Database.Batchable<SObject>,Database.Stateful,Database.AllowsCallouts {

    public String query;
    public Integer count;

    // 构造函数,可以动态传入where条件
    global MyBatchClass(String whereStr) {
        query = 'select Id,Name from Order where date >=' + whereStr;
        count = 0;
    }

    // 开始批处理,返回的是QueryLocator,该方法执行一次
    global Database.QueryLocator start(Database.BatchableContext bc)
    {
        return Database.getQueryLocator(query);
    }

    // 执行批处理(多线程分批处理),lists是分批查询的结果,该方法执行多次
    global void execute(Database.BatchableContext bc, List<Order> lists)
    {
        // 累加count值
        count++;

        // do sth. 分批次批量处理lists
        // 根据实际业务逻辑进行处理
    }

    // 批处理执行完成,可以做一些收尾工作,该方法执行一次
    global void finish(Database.BatchableContext bc)
    {
        // 如果不实现Database.Stateful接口,那么count=0(依然是构造函数中的赋值),不会记录上下文的count++
        System.debug(count);

        // 与批处理相关的job的信息
        AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,TotalJobItems, CreatedBy.Email FROM AsyncApexJob WHERE Id = :bc.getJobId()];

        // 收尾工作,比如发送邮件
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {a.CreatedBy.Email};
        mail.setToAddresses(toAddresses);
        mail.setSubject('Apex Sharing Recalculation ' + a.Status);
        mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +' batches with '+ a.NumberOfErrors + ' failures.');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
}

// 执行批处理
// 第2个参数500表示一次执行500条,取值范围:1-2000,默认值:200
// 比如一共20000条数据,一次执行500条,那么需要执行40次,上面累加的count就等于40
MyBatchClass mbc = new MyBatchClass();
Id = batchId = Database.executeBatch(mbc,500);

队列

队列用的比较少,一般用Future就行了

对顺序有需求或者需要嵌套异步处理的时候,可以考虑使用queue


// 定义队列任务
public class AsyncExecutionExample implements Queueable {
    public void execute(QueueableContext context) {
        Account a = new Account(Name='BestLove', Phone='13888888888');
        insert a;        
    }
}

// 入队
ID jobID = System.enqueueJob(new AsyncExecutionExample());

// 查看任务运行状况
AsyncApexJob jobInfo = [SELECT Status,NumberOfErrors FROM AsyncApexJob WHERE Id=:jobID];

// 队列中调用队列
public class AsyncExecutionExample implements Queueable {
    public void execute(QueueableContext context) {

        // Do Sth

        System.enqueueJob(new SecondJob());
    }
}

测试队列


@isTest
public class AsyncExecutionExampleTest {
    static testmethod void test1() {

        Test.startTest();        
        System.enqueueJob(new AsyncExecutionExample());
        Test.stopTest();

        // 等
        Account acct = [SELECT Name,Phone FROM Account WHERE Name='BestLove' LIMIT 1];
        System.assertNotEquals(null, acct);
        System.assertEquals('13585530842', acct.Phone);
    }
}

定时任务

  • 1次最多100个定时任务
  • 必须声明为 global 或 public
  • 定时任务和批处理任务可以结合使用
  • 也可以在后台设置 设置 -> APEX类 -> 计划 APEX
  • 查看进行中的计划,设置 -> 搜索计划 -> 找到计划的作业

global class scheduledMerge implements Schedulable {
   global void execute(SchedulableContext sc) {
      // do sth. 定期执行
   }
}

// 在开发人员控制台中执行此示例
scheduledMerge m = new scheduledMerge();
String sch = '20 30 8 10 2 ?';
String jobID = system.schedule('Merge Job', sch, m);

results matching ""

    No results matching ""