【Salesforce】非同期処理 QueueableとSchedulableの比較

以下は、QueueableとSchedulableの比較表と、それぞれの特徴を解説した内容です。

---

# QueueableとSchedulableの比較

Apexでは、非同期処理やスケジュール処理を行うために **Queueable** と **Schedulable** の2つのインターフェースが提供されています。この記事では、それぞれの特徴や使用例、メリット・デメリットについて比較し、適切な選択の指針を示します。

---

## 比較表

| **項目**                 | **Queueable**                                                                                               | **Schedulable**                                           |
|--------------------------|------------------------------------------------------------------------------------------------------------|----------------------------------------------------------|
| **主な用途**             | 非同期処理の実行、ジョブのチェーン、外部Web APIのコールアウト                                            | 定期実行、長時間の遅延ジョブ                                                                  |
| **使用するインターフェース** | `Queueable`                                                                                              | `Schedulable`                                            |
| **遅延のサポート**        | 最大10分まで (`System.enqueueJob(queueable, delay)` を使用)                                               | 任意の時間設定が可能 (`cronExpression` を使用)                                              |
| **ジョブのチェーン**      | サポート（1つのジョブから次のジョブをキューに追加可能）                                                   | サポートされない                                         |
| **引数のサポート**        | 非プリミティブ型（SObjectやカスタム型）も渡せる                                                          | サポートされない（情報は別途カスタム設定やレコードで管理する必要あり）                        |
| **制限事項**             | 1つのトランザクションで50ジョブまで追加可能<br>チェーンの最大深度はDeveloper組織では5（他の組織は制限なし） | 1時間に最大100件のスケジュールジョブ                                                          |
| **主な使用例**           | 外部システムとの連携、ポーリング処理、非同期で重い処理を実行                                             | 毎日/毎週の定期処理、非同期ジョブの遅延実行                                                   |
| **コールアウトのサポート** | `Database.AllowsCallouts` を実装すれば可能                                                              | コールアウトはサポートされない（ただしQueueableと組み合わせることで可能）                    |
| **ガバナ制限緩和**        | ヒープサイズ制限などが緩和                                                                                | 緩和されない                                             |

---

## 特徴と使用例

### Queueableの特徴と使用例
Queueableは、非同期処理を実行する際に便利です。`System.enqueueJob` を使用してジョブをキューに追加することで、独立したスレッドとしてバックグラウンドで処理を実行します。

#### **メリット**
- **非同期処理をチェーンで実行可能**:
  前のジョブが完了してから次のジョブを実行する、依存関係のある処理に最適です。
- **非プリミティブ型の引数をサポート**:
  SObjectやカスタム型のデータを渡すことで柔軟な設計が可能です。
- **ガバナ制限が緩和**:
  ヒープサイズや一部の制限値が緩和されます。

#### **デメリット**
- **遅延の上限が10分**:
  長時間の遅延が必要な場合にはSchedulableとの併用が必要です。

#### **使用例**
1. 外部システムのポーリング処理:
   ```apex
   public class PollingQueueable implements Queueable, Database.AllowsCallouts {
       public void execute(QueueableContext context) {
           // 外部APIからステータス取得
           Http http = new Http();
           HttpRequest request = new HttpRequest();
           request.setEndpoint('https://api.example.com/status');
           request.setMethod('GET');
           HttpResponse response = http.send(request);
           System.debug('Response: ' + response.getBody());
       }
   }
   ```
   - ジョブをキューに追加:
     ```apex
     System.enqueueJob(new PollingQueueable());
     ```

2. データ処理ジョブのチェーニング:
   ```apex
   public class ParentJob implements Queueable {
       public void execute(QueueableContext context) {
           System.debug('Parent job running');
           System.enqueueJob(new ChildJob());
       }
   }
   public class ChildJob implements Queueable {
       public void execute(QueueableContext context) {
           System.debug('Child job running');
       }
   }
   ```

---

### Schedulableの特徴と使用例
Schedulableは、特定の時間や間隔でジョブを実行したい場合に適しています。`System.schedule` メソッドを使用してジョブをスケジュールします。

#### **メリット**
- **任意の時間指定が可能**:
  Cron形式を使用することで、柔軟なスケジュール設定が可能です。
- **長時間の遅延ジョブに適している**:
  10分以上の遅延が必要な場合に活用できます。

#### **デメリット**
- **チェーニングがサポートされていない**:
  ジョブが単独で動作する場合に適しています。

#### **使用例**
1. 定期処理ジョブ:
   ```apex
   global class DailyBatchJob implements Schedulable {
       global void execute(SchedulableContext context) {
           System.debug('Daily batch job running');
       }
   }
   ```
   - ジョブをスケジュール:
     ```apex
     String cronExp = '0 0 12 * * ?'; // 毎日正午に実行
     System.schedule('Daily Batch Job', cronExp, new DailyBatchJob());
     ```

2. Queueableとの組み合わせ:
   - QueueableジョブをSchedulableでスケジュール:
     ```apex
     global class ScheduledQueueableJob implements Schedulable {
         global void execute(SchedulableContext context) {
             System.enqueueJob(new PollingQueueable());
         }
     }
     ```

---

## 適切な選択のためのガイド

1. **非同期で即時または最大10分以内の遅延** → **Queueable**
   - 外部システムへの短いポーリングや非同期データ処理。

2. **10分以上の遅延、または定期的な処理** → **Schedulable**
   - 定時のデータ更新や長期的なスケジュール処理。

3. **複雑なフロー (チェーニング + 長時間遅延)** → **Queueable + Schedulable**
   - チェーンを組み合わせつつ、定期的な実行を行う場合。

---

## まとめ

QueueableとSchedulableは、それぞれの特徴を活かすことで、効率的に非同期処理やスケジュール処理を設計できます。要件に応じて適切な選択を行い、必要に応じて両者を組み合わせることで、Salesforceでの複雑なワークフローも実現可能です。