チームスピリット Advent Calendar 2021:いまさら聞けない非同期Apexのはなし
- ごあいさつ
- Apexバッチ(Bachable)
- Apexスケジューラ(Schedulable)
- 1.@futureメソッド
- 2.キュー可能Apex
- 3.Apexバッチ
- 4.Apexスケジューラ
- おわりに
この記事は、チームスピリット Advent Calendar 2021 1日目 の記事です。(公開日は気にするな!)
ごあいさつ
皆様こんにちは。相変わらずの親方です。
最近よく弄る機会があるので、Apex処理の「非同期Apex」について、思いついたTipsを書いてみました。
なにかとガバナ制限に縛られるApex開発において、トランザクションの壁を越えられる非同期処理は大量データの処理に不可欠です。「最近、Apexの変なエラーが止まらないの・・・」という方は必読です。
リファレンスはこちら
https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_async_overview.htm
非同期Apexの特徴
メリット
- ガバナ制限が緩和される
- 大量データ処理ができる
- スケジュール起動ができる
- ポーリング的な処理も組める
- 非同期でしかアクセスできないオブジェクトもある
デメリット
非同期Apexの一覧
Apex では、複数の方法で Apex コードを非同期に実行できます。ニーズに最も合う非同期 Apex 機能を選択してください。次の表は、非同期 Apex 機能とそれぞれを使用するケースの一覧です。
| @future メソッド | |
| キュー可能 Apex (Queueable) |
|
Apexバッチ(Bachable) |
|
Apexスケジューラ(Schedulable) |
|
1.@futureメソッド
もっとも簡単に実装できる非同期Apexです。staticなメソッドに"@future"アノテーションをつけるだけ!シンプルだけどガバナ制限を緩和するには十分使えます。
失敗した場合にハンドリングがきかないので、コケても構わない処理をやりましょう。
同期/非同期の両方で使えるメソッドを作る
とはいえコケたら困るのでちゃんとロールバックできる形で実行したい・・・そんなときもあると思います。以下のように実装すれば、呼び出し方の違いで簡単に同期/非同期を切り替えられます。
2.キュー可能Apex
Queueableインターフェースを実装することで使える、上の@futureよりしっかり使えるクラスです。具体的には
- ジョブIDを返すため、後からSOQLで実行成否を確認できる
- コケた時にリカバリ処理を実装できる:Transaction Finalizersを使う
- メンバー変数を定義できるので、無制限なデータ型の項目を事前に引き渡せる
- 非同期Apex処理を更に1つ呼べるので、それを繰り返すことで常駐処理が組める(使いすぎに注意!)
複数のApexトリガから呼べる汎用非同期ハンドラ
Apexトリガのハンドラを非同期化することで、レコード保存の待機時間を減らすことができます。それだけなら@futureでもできるのですが、引数をSObjectにすることで処理を汎用化できます。
非同期Apexクラス
呼び出し元のトリガ
3.Apexバッチ
言わずと知れた、5000万件の大量処理ができる神のような機能です。ListもしくはSOQLの検索結果を引数として、その件数分だけの非同期処理ができます。夜間に定期実行させているところも多いのでは?
実はバッチサイズを変えられる
ApexバッチはDatabase.executeBatch()で起動しますた、実はこの第二引数にバッチサイズを入れられます。これにより最小1~2000件単位(クエリから実行する場合、リストを渡す場合はそれ以上可)まで処理件数を変えられます。一部処理でガバナ制限エラーが発生したときは件数を減らしてみましょう。
Apexバッチ
バッチの呼び出し
実はそのままでスケジューリングできる
バッチを定時起動するために口述のスケジュール起動と組み合わせている実装も多いと思います。ですが実はApexバッチはSchedulableでなくともスケジュールする方法があるんです。System.scheduleBatch()を使います。
時刻指定はcronではなく○○分後、1回のみ起動します。
4.Apexスケジューラ
標準のスケジューラ、もしくはcron表記で定時実行ジョブを登録できます。普通にやると単独の非同期トランザクションになりますが、バッチの起動トリガにも使えます。
Apexバッチをスケジュール可能にする
もはやこれが通常運用なのかもしれないという程メジャーな運用ですが、BachableとSchedulableクラスがそれぞれ有るとかさばるので纏めちゃいましょう。ちょっと運用しやすくなります。
直接スケジューラ登録可能なApexバッチ
おわりに
あんまり日本語で情報出てなさそうなTipsを探してみました。普段当たり前にやってるけど実は他の人が知らないことって意外とあると思います。見えるところに書いておくだけでも後々いいことありそうですね。
それではまた!