【Salesforce】Queueableの基本(enqueueJob/実行順/制限)を1ページで

Queueableって、便利なんですが「なんとなく」で触ると地味に事故ります。

自分も最初は、テストは通るのに本番で順番がズレたり、制限に当たって詰まったりしました。

ってことで結論です。

結論:Queueableは『enqueueJobでキューに積まれる非同期処理』。

実行順と制限を押さえて、設計をシンプルにすると安定します。

次に読む
非同期テストの次は「Queueable自体の基本」です。 enqueueJobの動き方、実行順、よく踏む制限をまとめました。
【Salesforce】Queueableの基本(enqueueJob/実行順/制限)を読む →

Queueableとは?

Queueableは、Apexの非同期処理の1つです。

同期処理(通常のApex)とは違い、実行は「今すぐ」ではなく『キューに積まれて後で実行』されます。

よく使う理由はこのへんです。

  • 画面やトリガの処理を軽くできる(ユーザの待ち時間が減る)
  • 処理を分割して段階的に進められる
  • バッチほど大げさにせず、非同期化できる

enqueueJobの最小形(まずはこれだけ)

Queueableの基本形はこうです。

Queueableクラス(最小)

public class SampleQueueable implements Queueable {
public void execute(QueueableContext context) {
// ここに非同期でやりたい処理を書く
System.debug('Queueable executed');
}
}


呼び出し側(enqueueJob)

System.enqueueJob(new SampleQueueable());

これで『キューに積まれる』までが確定します。

実行順はどう決まる?

ここが一番の落とし穴になりやすいです。

結論から言うと、Queueableは『キューに積まれた順で実行される』と考えるのが基本ですが、現実はもう少し注意が必要です。

まず押さえる前提

  • enqueueJobした瞬間に実行されるわけではない
  • 実行タイミングはSalesforce側(プラットフォーム側)が管理する
  • だから「この順で必ず動く」を前提に設計すると痛い

じゃあどう設計する?

順番が大事な処理は、次のどれかに寄せるのが堅いです。

  • 1つのQueueableで完結させる(分割しない)
  • 分割するなら『チェーン(連鎖)』して順番を固定する
  • そもそも順番に依存しない設計に寄せる(理想)

チェーン(連鎖)で順番を固定する

Queueableは、executeの中で次のQueueableをenqueueできます。

これで「次にこれ」を作れます。

public class Step1Queueable implements Queueable {
public void execute(QueueableContext context) {
// Step1の処理
// ...

// 次の処理へ
System.enqueueJob(new Step2Queueable());
}
}

public class Step2Queueable implements Queueable {
public void execute(QueueableContext context) {
// Step2の処理
// ...
}
}

注意:チェーンは強いですが、やりすぎると制限に当たります(後述)。

よく踏む制限(最低限これだけ)

Queueableは「無限に投げられる」わけではないです。

制限は細かくありますが、現場で踏みやすいのはこの3つです。

1) 1回のトランザクションでenqueueできる数に上限がある

トリガやフロー、Apex処理の中でループしながらenqueueすると、すぐ危険です。

ダメな例(雰囲気)

for(Account a : accounts){
System.enqueueJob(new SampleQueueable()); // これを大量にやると危険
}

対策:enqueueは『1回』に寄せて、Queueableの中でまとめて処理する。

2) チェーン(連鎖)にも上限がある

「Step1 → Step2 → Step3 → …」を無限に繋ぐ設計は危険です。

対策:

  • 連鎖は最小限(本当に順番が必要な部分だけ)
  • 大量処理ならBatchを検討
  • 途中状態はレコード(ステータス)で管理して、再実行可能にしておく

3) 同時実行・再実行で二重更新が起きやすい

Queueableは「後で動く」ので、同じ対象に対して別のQueueableが走ると衝突します。

結果として、上書きやロック、想定外の更新が起きます。

対策:

  • 対象レコードに『処理中フラグ』や『バージョン番号』を置いてガードする
  • そもそも同じ対象を並列で触らない設計に寄せる
  • 失敗しても再実行できる形にする(1回で完璧を狙わない)

どうテストする?(最小だけ)

Queueableは、テストで『startTest/stopTest』で挟むのが基本です。

@IsTest(SeeAllData=false)
public class SampleQueueableTest {
@IsTest
static void testQueueable() {
Test.startTest();
System.enqueueJob(new SampleQueueable());
Test.stopTest();

// stopTest後に検証を書く
System.assertEquals(true, true);
}
}

「検証ができない」で詰まる場合は、Queueableが更新する対象(項目)を用意して、stopTest後にSELECTして確認するのが堅いです。

まとめ

  • Queueableは『enqueueJobでキューに積まれる非同期処理』
  • 実行順は「保証される」と思い込みすぎない(順番が必要ならチェーンで固定)
  • 制限は踏みやすい(enqueue乱発、チェーン過多、二重更新)
  • テストは『startTest/stopTestで挟んで、stopTest後に検証』
次に読む
ここまで来たら、テストが落ちにくくなる前提を固めるのが先です。 SeeAllData=false の意味・使いどころ・注意点を1ページでまとめました。
【Salesforce】@IsTest(SeeAllData=false)とは?意味・使いどころ・注意点を読む →

おすすめの記事