(最終更新月: 2023年12月)
✔以下の疑問をお持ちの方へ向けた記事です
「SalesforceでBatch Apexを使う目的は何か?」
「Batch Apexの基本的なコーディング方法とは?」
「Batch Apexを実際に使用する際のベストプラクティスは?」
✔当記事を読むことで得られる知識
- SalesforceにおけるBatch Apexの概念と使用目的
- Batch Apexの基本的な実装方法
- Batch Apexの効果的な使用に関するヒントとベストプラクティス
当記事では、大量のデータを処理するためのSalesforceのツールであるBatch Apexについて、開発における基本的な構造、スケジュール設定、例外処理などに焦点を当て、具体的なコーディング例を通じてその使い方を説明します。
Salesforce開発者や管理者にとって役立つガイドです。
ぜひ最後までご覧ください。
Batch Apexの基本
こちらでは、Salesforceでのアプリケーション開発において重要な役割を果たすBatch Apexについて詳しく解説します。
Batch Apexを理解することで、大量のデータ処理など複雑な処理を効率的に扱うことが可能です。
- Batch Apexとは何か
- Batch Apexの使用シナリオと利点
- Batch Apexと通常のApexの違い
Batch Apexとは何か
Batch Apexは、Salesforce内で大量のデータレコードに対して処理をする際に使用される強力なツールです。
とくに一括処理や複雑なビジネスロジックを適用する必要がある場合には、Batch Apexが非常に役立ちます。
以下は簡単なBatch Apexのサンプルコードです。
public class MyCustomBatch implements Database.Batchable<SObject> {
public Database.QueryLocator start(Database.BatchableContext bc) {
String testState = '';
if (Test.isRunningTest()){
//テスト時はLIMITでレコード数をコントロールする必要がある
testState = ' LIMIT 200';
}
String query = 'SELECT Id, StageName FROM Opportunity WHERE StageName = \'Close Won\'' + testState;
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext bc, List<Opportunity> scope){
System.debug('size: ' + scope.size());
for (SObject sobj: scope){
System.debug('sobj: ' + sobj);
Opportunity opp = (Opportunity)sobj;
System.debug('opp: ' + opp.StageName);
}
}
public void finish(Database.BatchableContext bc){
System.debug('finish!');
AsyncApexJob job = [
SELECT Id, Status, NumberOfErrors,
JobItemsProcessed,
TotalJobItems, CreatedBy.Email
FROM AsyncApexJob
WHERE Id = :bc.getJobId()
];
System.debug('job: ' + job.Id);
System.debug('job: ' + job.Status);
System.debug('job: ' + job.NumberOfErrors);
}
}
このコードは、Batch Apexクラスを実装する基本的な枠組みを示しており、開発者はこの枠組み内で独自のビジネスロジックを構築できます。
Batch Apexの使用シナリオと利点
Batch Apexはさまざまなシナリオで使用可能ですが、主に大量のデータ操作を伴う処理に適しています。
例えば、以下のような場面です。
- データマイグレーション
- データクリーニング
- 複雑な計算
- 定期的なデータメンテナンス
Batch Apexの利点は、大量データの処理を少数のレコードごとに分割して実行すること。
Salesforceのガバナ制限に抵触するリスクを最小限に抑えられ、システムの安定稼働を保てるのです。
Batch Apexと通常のApexの違い
Batch Apexと通常のApexクラスの大きな違いは、処理の仕組みにあります。
通常のApexはリアルタイムで実行され、リクエストごとに完了する必要があります。
対してBatch Apexは、指定されたバッチサイズに基づいてレコードを分割し、それぞれの小さい単位(バッチ)で非同期に処理をおこないます。
これにより、大量のレコードに対して時間をかけて順次処理をおこなえるのです。
Batch Apexの開発プロセス
Batch Apexを用いた開発の流れを把握することは、効果的なコードを書く上で不可欠です。
以下のステップで、Batch Apexの開発プロセスを体系的に理解していきましょう。
- Batch Apexクラスの作成
- execute、start、finishメソッドの定義
- バッチサイズとトランザクションの管理
Batch Apexクラスの作成
Batch Apexクラスを作成するには、Database.Batchableインターフェースを実装する必要があります。
このインターフェースに含まれているのは、以下3つのメソッドです。
- start
- execute
- finish
新しいBatch Apexクラスは通常次のように始まります。
global class MyBatchClass implements Database.Batchable<sObject> {
// ここに実装していく
}
この枠組みの中で具体的なビジネスロジックを定義していきます。
execute、start、finishメソッドの定義
それぞれのメソッドについて見ていきましょう。
各メソッドが実行されるタイミングを理解して、その役割を把握しましょう。
start
メソッド:
バッチ処理を開始する際に一度だけ呼び出され、処理するレコードの選択条件を指定execute
メソッド:
バッチ内の各レコードに対して定義した処理をおこなうfinish
メソッド:
バッチ処理が完了した後に一度だけ実行され、通知の送信やログの作成などをおこなう
バッチサイズとトランザクションの管理
バッチサイズは、一度に処理されるレコードの数を指定する値のこと。
トランザクションの管理は、Database.executeBatchメソッドを呼び出す際にバッチサイズを設定します。
例えば、以下のコードでバッチサイズを200としてバッチ処理を開始できます。
Id batchId = Database.executeBatch(new MyBatchClass(), 200);
適切なバッチサイズの設定により、処理のパフォーマンスを最適化し、ガバナ制限を効果的に回避できます。
Batch Apexの実践的な応用
Batch Apexを実際のプロジェクトに適応するためには、その応用方法を理解し、的確に設計・実装する必要があります。
以下の応用例を参照して、Batch Apexをより効果的に利用しましょう。
- 大量データ処理の最適化
- スケジュールされたバッチジョブの設定
- バッチ処理のエラーハンドリング
大量データ処理の最適化
大量のデータを効率的に処理するためには、以下などが必要です。
- クエリの最適化
- 適切なバッチサイズの選定
- 並行処理の活用
バッチ処理は通常、start
メソッドで生成されたQueryLocatorオブジェクトを使用してデータを取得。
このQueryLocatorオブジェクトを利用して、データをバッチに分けてexecute
メソッドで処理します。
スケジュールされたバッチジョブの設定
定期的に実行する必要があるバッチジョブは、Database.executeBatch
メソッドを利用してスケジューリングが可能。
これにより、特定の時間にバッチジョブを自動的に起動できます。
以下はスケジュール設定の例です。
// Schedule the batch to run every day at 3 AM.
String cronExp = '0 0 3 * * ?';
System.schedule('Daily Data Cleanup', cronExp, new ScheduledBatch());
バッチ処理のエラーハンドリング
エラーが発生した場合に備えて、Batch Apexには例外処理のメカニズムを組み込むべきです。
execute
メソッド内でエラーが発生しやすい操作をする際には、try-catch
ブロックを使用して例外を捕捉し、エラーハンドリングをおこないましょう。
これにより、失敗したレコードを記録し、後で調査できます。
Batch Apexのテストとデバッグ
効率的で安全なBatch Apexのコードを確実に実装するためには、テストとデバッグが不可欠です。
この工程を通じて、コードが期待通りに動作するかを確認し、必要に応じて修正を加えます。
- テストクラスの作成と実行
- データカバレッジとテストシナリオ
- デバッグとパフォーマンスの監視
テストクラスの作成と実行
Batch Apexをテストするためには、専用のテストクラスを作成します。
テストメソッド内ではテストデータを生成し、Test.startTest
とTest.stopTest
ブロックを使用してバッチ処理を実行。
これにより、非同期処理が同期的に実行され、テスト結果をすぐに確認できます。
@IsTest
private class MyCustomBatchTest {
private final static Integer numOfRecords = 500;
@TestSetup
static void setUp(){
List<Opportunity> opps = new List<Opportunity>();
for (Integer i=0; i<numOfRecords; i++){
Opportunity opp = new Opportunity(
Name='test '+i,
StageName='Close Won',
CloseDate=Date.today().addDays(10)
);
opps.add(opp);
}
insert opps;
}
/** batch test*/
@IsTest static void testBatch(){
Test.startTest();
MyCustomBatch mcb = new MyCustomBatch();
Id batchId = Database.executeBatch(mcb, numOfRecords);
Test.stopTest();
System.assertNotEquals(null, batchId);
}
}
データカバレッジとテストシナリオ
Salesforceは少なくとも75%のコードカバレッジを要求していますが、できるだけ高いカバレッジを目指すことが望ましいです。
実際のデータに似たシナリオを作成し、バリエーション豊かなテストデータを用いて、さまざまな条件下でのバッチ処理の挙動を確認しましょう。
テスト実行の際は以下の手順でおこなうとカバー率とその対象クラスが確認できます。
管理者コンソール > テスト >
デバッグとパフォーマンスの監視
デバッグログを利用して、実行時の挙動を監視し、問題の原因を調査します。
パフォーマンスの監視には、処理時間やCPU時間などの指標をチェックし、バッチ処理の最適化につなげてください。
また、System.debug
ステートメントを適切に配置し、処理中の変数の値をログに出力してデバッグ作業を助けましょう。
Batch Apexのベストプラクティス
Batch Apexを最適に活用するためには、一般的なベストプラクティスを知り、これを実践することが重要です。
ここでは、Batch Apexを使用する際に心がけるべきベストプラクティスを紹介します。
- ガバナ制限とリソース管理
- パフォーマンス最適化のためのヒント
- メンテナンスとコードの拡張性
ガバナ制限とリソース管理
Salesforceには各種ガバナ制限が設定されています。
Batch Apexを使用する際は、これらの制限に注意しながら設計をおこないましょう。
例えば、SOQLクエリの発行回数やDML操作の制限など、に気をつけることが求められます。
これらの制限値を超えないようにコードを慎重に記述し、必要なリソースを効率良く利用してください。
パフォーマンス最適化のためのヒント
Batch Apexのパフォーマンスを向上させるには、適切なデータ分割や並行実行の管理、および処理の軽量化が重要です。
クエリをチューニングして実行負荷を減らす、必要なフィールドのみを取得する、大きなトランザクションをより小さな単位に分割するなどの工夫をおこないましょう。
メンテナンスとコードの拡張性
将来的にコードの変更や拡張が必要になる可能性を考慮して、可読性とメンテナンスの容易さを確保することが大切です。
また、バッチ処理を再利用可能かつ拡張可能にするために、モジュラーな設計を心がけると良いでしょう。
まとめ
Batch Apexは、Salesforceでの大量データ処理において不可欠なツールです。
当記事では、Batch Apexの基本からテスト、デバッグ、そしてベストプラクティスまでを詳しく解説しました。
これらの知識を活用することで、Salesforce開発における効率的かつ効果的なBatch Apexの統合が可能になるでしょう。
常に最新のドキュメントやコミュニティのリソースを参考にして、スキルを磨き続けてください。