😊
Salesforceフローで一括処理(Database.Batchable)を呼び出す
こんにちは。バニッシュ・スタンダードの土屋と申します。今回はSalesforceの話です。
きっかけ
普段使っているフローがコケるようになってしまいました。
「制限を超えました。お客様の組織はこの機能に対する最大限度を超えました。」
クエリ総数100件やクエリ取得50000件といったガバナ制限は意識していたのですがSalesforce サーバーの最大CPU時間10,000ミリ秒超えはどうにも対応ができず。
フローが限界に来ているようなのでApexと組み合わせて処理を実行することにしました
処理の流れ
- フローからInvocableMethodを呼び出す
- InvocableMethodからBatchableを呼び出す
実装
実装は処理の流れとは逆に実装していきます。
一括処理(Database.Batchable)
いわゆる非同期処理です。Database.Batchableインターフェースでstartメソッド,executeメソッド,finishメソッドを実装します。
/**
* サンプル
*/
public class SampleBatchable implements Database.Batchable<SObject>, Database.Stateful {
private Integer processCount; // 処理件数
public SampleBatchable() {
processCount = 0;
}
/**
* startメソッド
* Apex の一括処理ジョブの開始時に呼び出されます
* executeに渡すクエリを生成します
* 今回のサンプルではすべての取引先を取得しています
*/
public Database.QueryLocator start(Database.BatchableContext bc) {
Database.QueryLocator query =Database.getQueryLocator([
SELECT Id,Name FROM Account
]);
return query;
}
/**
* executeメソッド
* メソッドに渡すレコードのバッチごとに呼び出されます。
*/
public void execute(Database.BatchableContext bc, List<Account> accounts) {
// 実処理の実装
for(Account account : accounts) {
// --------------------------
// ここに処理を書く
// --------------------------
processCount += 1;
}
}
/**
* finishメソッド
* すべてのバッチが処理された後に呼び出されます
* 通知や後処理を実装できます
*/
public void finish(Database.BatchableContext bc) {
System.Debug('対象件数 = ' + processCount);
}
}
Batchableを使うときに気をつけること
- 処理の順番が保証されません
- 最初のトランザクションが成功し、2番目が失敗した場合、最初のトランザクションで行われたデータベースの更新はロールバックされません。
InvocableMethod
フローから呼び出せるアクションを定義するInvocableMethodアノテーションを使用します
public with sharing class SampleInvocable {
@InvocableMethod(
label = 'サンプル'
description = 'サンプル説明文'
)
public static List<String> execute() {
List<String> resultMessage = new List<String>();
try {
SampleBatchable batchInitial = new SampleBatchable();
Database.executeBatch(batchInitial, 1);
resultMessage.add('OK');
} catch (Exception e) {
resultMessage.add('ERROR');
resultMessage.add(e.getTypeName());
resultMessage.add(e.getMessage());
resultMessage.add(e.getStackTraceString());
}
return resultMessage;
}
}
フローから呼び出し
処理結果
無事に処理が実行できました
まとめ
コーディングなしで実装できるフローはとても便利なのですがまだ限界があるのでうまくApexと組み合わせていけるといいのかなと思いました。
Discussion