見出し画像

[Salesforce]Apex非同期処理:Futureメソッドの活用

今回は、Salesforce開発で頻繁に利用される「非同期処理」と「@future メソッド」について、実践的な内容を掘り下げて解説します。
以前、こちらの記事で同様の内容を記載していたのですが、だいぶわかりづらかったためアップデートするために改めて取り上げました。さらに、Queueable Apex との違いを詳しく解説し、どちらを使うべきかの判断材料を提供します。

非同期処理の重要性と現場でのユースケース


Salesforce開発では、同期的に処理を行うとガバナ制限(SOQLクエリ制限、DML操作の制限など)に引っかかることがよくあります。特に大量データを操作する場合や、時間のかかる複雑な処理を行う場合は、この問題が顕著になります。
例えば:
大量のレコード更新が必要:数万件のレコードを一度に更新する際、同期処理ではガバナ制限に達してしまう。
外部システムとの連携:APIを使った外部システムとのデータ連携処理は、時間がかかるため非同期的に行いたい。
大量のレポート生成:夜間に大量のレポートを一斉に生成する必要があるが、業務時間中には負荷をかけたくない。

こうしたシナリオでは、非同期処理が強力なツールとなります。特に、ガバナ制限を回避しながら安全に大量データを扱うためには、@future や Queueable Apex の活用が不可欠です。

Futureメソッドの使い方とルール

まずは、Salesforceで最も基本的な非同期処理の手法である**@future メソッド**について見ていきましょう。

基本的な書き方

global class FutureClass {
    @future
    public static void myFutureMethod() {
        // 非同期処理のロジック
    }
}

覚えておくべきルール

• メソッドは static でなければならず、戻り値は void のみ。
• 1日に実行できる future メソッドの最大数は、250,000回またはユーザライセンス数の200倍。
• future メソッドの実行順序は保証されない。
• sObject を直接引数に取ることはできない(プリミティブ型やその配列・コレクションのみ)。

実践シナリオ:sObjectを扱う場合

問題の発生例

@future メソッドでは sObject を引数として渡すことができません。
例えば、以下のコードはエラーになります:

@future
public static void createTask(List<Opportunity> newOpps) {
    // エラーが発生する
}

これは、非同期処理がキューに入って実行されるまでの間に sObject のデータが変更される可能性があるためです。

解決策:Id を使用

この問題を解決するには、sObject の代わりにレコードの Id を渡して、そのIdを使ってデータを再取得する方法が効果的です。

@future
public static void createTask(Set<Id> oppIds) {
    List<Task> tasks = [SELECT Id FROM Task WHERE WhatId IN :oppIds];
    // タスク処理を実行
}

これにより、レコードをIdで特定し、非同期処理中でも安全にデータ操作が可能になります。

トリガーで非同期処理を使う

トリガーから非同期処理を呼び出したい場合、Trigger.new のようなコンテキスト変数を直接渡すことはできません。しかし、以下のようにIdセットを使うことで非同期処理を呼び出せます。

public static void setIdAndCallFuture(List<Opportunity> opps) {
    Set<Id> oppIds = new Set<Id>();
    for (Opportunity opp : opps) {
        oppIds.add(opp.Id);
    }
    createTask(oppIds);
}

このように、トリガー内で Id セットを作成し、それを @future メソッドに渡すことで、非同期処理を安全に実行できます。

@futureとQueueable Apexの違い

次に、@future と Queueable Apex の違いを見てみましょう。どちらも非同期処理を行うための手段ですが、Queueable Apexはより柔軟で拡張性の高いオプションです。

1. 引数の制約

@future:プリミティブ型、プリミティブ型の配列、コレクションのみ使用可能。sObject を直接渡せません。
Queueable Apex:sObject を含むオブジェクトを引数に取ることが可能です。これにより、データ操作の柔軟性が大幅に向上します。

2. チェイニングの可否

• @future:他の future メソッドを呼び出すことはできません(チェイニング不可)。
• Queueable Apex:System.enqueueJob を使うことで、ジョブを連鎖的に実行する(チェイニング)ことが可能です。複数の非同期処理を連続的に実行する場合に非常に便利です。

3. 可視性とデバッグ

@future:ジョブIDなどの取得ができないため、ジョブの状態を簡単に追跡したりデバッグするのが難しいです。
Queueable Apex:Job ID が取得可能で、System.enqueueJob で返されたIDを使ってジョブの状態を監視し、デバッグがしやすくなります。

4. ガバナ制限

@future:1つのトランザクション内で呼び出せる future メソッドの数には制限があります(50件まで)。
Queueable Apex:同じく1トランザクション内で50件までのジョブを呼び出せますが、@future よりも柔軟性があり、特にチェイニングを利用した複雑なシナリオで有利です。

非同期処理のベストプラクティスとデバッグのヒント

1. 非同期処理は適切にスケジュールする

非同期処理はリアルタイム性が不要な場面で活用しましょう。システムの負荷が少ない時間にスケジュールすることで、パフォーマンスを最大限に引き出せます。

2. Queueable Apexの利用を検討する

より複雑なシナリオや、引数に sObject を使う必要がある場合は、Queueable Apex が有効です。エラーハンドリングやデバッグがしやすい点も魅力です。

3. 非同期処理のデバッグ

非同期処理のデバッグはやや難しいため、Queueable Apex を使用してジョブIDを追跡し、ジョブの状態を確認できるようにしましょう。また、ジョブの実行ログを確認することで、エラーの特定と改善が容易になります。

4. 例外処理とリトライ戦略を考える

非同期処理中に失敗が発生した場合、リトライ戦略やエラーログの出力を考慮しましょう。これにより、システムの信頼性を向上させることができます。

まとめ

非同期処理は、Salesforce開発においてガバナ制限を回避しつつ、効率的なシステム運用を可能にする強力な手法です。@future と Queueable Apex を理解し、それぞれの利点を活かすことで、よりパフォーマンスの高いシステムを構築できます。

@future メソッドは基本の非同期処理
シンプルな非同期処理に最適ですが、引数の制限に注意しましょう。

Queueable Apexの柔軟性を活用
より柔軟なデータ操作やエラーハンドリング、ジョブのチェイニングが可能なため、複雑な処理には最適です。

このガイドを参考に、非同期処理の理解を深め、より効率的なSalesforce開発に役立ててください!

この記事が気に入ったらサポートをしてみませんか?