Queueable Apex: Batch 和 Future 的结合
Queueable Apex允许你提交类似于Future方法的异步处理作业,还具有以下附加优点:
Non-primitive types:你的Queueable类可以包含非原始数据类型的成员变量,例如sObjects或自定义Apex类型。当作业执行时,可以访问这些对象。
Monitoring:当通过调用System.enqueueJob方法提交作业时,该方法返回AsyncApexJob记录的ID。您可以使用此ID来标识作业,并通过“Apex作业”页面中的Salesforce用户界面监视作业进度,也可以通过从AsyncApexJob查询记录来通过编程方式进行监视。
Chaining jobs:通过从正在运行的作业启动第二个作业,可以将一个作业链接到另一个作业。如果需要执行一些顺序处理,链接作业很有用
模板:
public class SomeClass implements Queueable {
public void execute(QueueableContext context) {
// awesome code here
}
}
public class UpdateParentAccount implements Queueable {
private List<Account> accounts;
private ID parent;
public UpdateParentAccount(List<Account> records, ID id) {
this.accounts = records;
this.parent = id;
}
public void execute(QueueableContext context) {
for (Account account : accounts) {
account.parentId = parent;
// perform other processing or callout
}
update accounts;
}
}
@isTest
public class UpdateParentAccountTest {
@testSetup
static void setup() {
List<Account> accounts = new List<Account>();
// add a parent account
accounts.add(new Account(name='Parent'));
// add 100 child accounts
for (Integer i = 0; i < 100; i++) {
accounts.add(new Account(
name='Test Account'+i
));
}
insert accounts;
}
static testmethod void testQueueable() {
// query for test data to pass to queueable class
Id parentId = [select id from account where name = 'Parent'][0].Id;
List<Account> accounts = [select id, name from account where name like 'Test Account%'];
// Create our Queueable instance
UpdateParentAccount updater = new UpdateParentAccount(accounts, parentId);
// startTest/stopTest block to force async processes to run
Test.startTest();
System.enqueueJob(updater);
Test.stopTest();
// Validate the job ran. Check if record have correct parentId now
System.assertEquals(100, [select count() from account where parentId = :parentId]);
}
}