非同期Apexの概要

#1.非同期Apexの種類
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/3382092e-0bf7-fe8f-0029-196b23ed328a.png)
#2.1.@futureメソッド
##一般的なシナリオ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/2a9c66cd-4606-b93f-3824-9e5ef882bf19.png)
##構文
```.java
public class SMSUtils {
    @future(callout=true)
    public static void sendSMSAsync(String fromNbr, String toNbr, String m) {
        String results = sendSMS(fromNbr, toNbr, m);
        System.debug(results);
    }

    public static String sendSMS(String fromNbr, String toNbr, String m) {
        String results = SmsMessage.send(fromNbr, toNbr, m);
        insert new SMS_Log__c(to__c=toNbr, from__c=fromNbr, msg__c=results);
        return results;
    }
}
```
##留意事项
- static void である必要あり。
- 引数はプリミティブ型、プリミティブ型の配列、プリミティブ型のコレクション

　　※sObjectが渡せない理由
 　　　メソッドをコールしてからそのメソッドを実際に実行するまでの間にオブジェクトが変更される可能性があるためです。

- future メソッドから future メソッドをコールすることはできません。
- future メソッドはコールされた順序で実行されるとは限りません。

#2.2.Queueableインターフェース
##一般的なシナリオ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/d61c0b37-0987-bd64-d9b9-92675b5f78c3.png)
##構文
```.java
public class XXQueueable implements Queueable {
    public XXQueueable(List<Account> records, ID id) {
        // 初期化処理
    }
    public void execute(QueueableContext context) {
        // 業務処理
    }
}
```
##留意事项
- 1トランザクションでSystem.enqueueJobを使用してキューに追加できる最大数は50。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/0b9e0d6b-822e-392b-d4ed-9121225b2836.png)

- 実行中のジョブからSystem.enqueueJobで追加できるジョブは1つのみ。
　※親キュー可能ジョブごとに1つの子ジョブしか存在できない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/a32a11e2-bc5c-b9fa-afb3-1e5d28777f57.png)

- Dev環境でのチェーニング最大スタック深度は5までなので注意。

#2.3.Schedulableインターフェース
##一般的なシナリオ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/90e8de2f-4ac4-7db7-7a00-8355072e930b.png)
##構文

```java

global class XXSchedulable implements Schedulable {
    global void execute(SchedulableContext ctx) {
        // 業務処理
    }
}
```
##スケジュール登録方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/113af77d-0465-c571-b008-47254899b0ca.png)

#2.4.Database.Batchableインターフェース
##一般的なシナリオ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/cf6c73a7-c172-433e-1d4f-25f3ac17b1ee.png)
##構文
```java
global class XXBatchable implements Database.Batchable<sObject> {
    // バッチの処理対象データ（1回のみ実行）
    global Database.QueryLocator start(Database.BatchableContext bc) {
        String strQuery = 'SELECT id, Name・・・FROM XX__c WHERE・・・';
        Database.getQueryLocator(strQuery);
    }
    
    // バッチサイズごとに実行する（複数回実行）
    global void execute(Database.BatchableContext bc, List<sObject> scope){
        // 業務処理
    }
    
    // バッチの後処理 (メール送信など)（1回のみ実行）
    global void finish(Database.BatchableContext bc){
      // 後続処理
    }
}
```
##留意事项
- Statefulバッチには、インスタンス変数のみがトランザクション間で値を保持できます。
- Statefulバッチのインスタンス変数はserialization「直列化」可能なデータ型が必要です。
- 複数バッチ並列で実行する場合、データLOCKの問題は要注意。
- バッチのテストする時、バッチサイズを超えてテストデータを作成すると、システムエラーが発生します。バッチの対象データはバッチサイズ内に作成する必要です。

#3.参照資料
- [Apex 開発者ガイド：非同期 Apex](https://developer.salesforce.com/docs/atlas.ja-jp.216.0.apexcode.meta/apexcode/apex_async_overview.htm)
- [Trailhead：非同期 Apex](https://trailhead.salesforce.com/ja/content/learn/modules/asynchronous_apex)