You need to sign in to do that
Don't have an account?
マスターキートン!
複数のオブジェクトにまだがる大量一括更新について
大量レコードを扱うにあたり、apex batchを実装しています。
その際、Aというオブジェクトから取得したデータをBに突っ込むといったケースの実装につきまして、
まずはじめに、startメソッドでAのデータを取得したのち
executeメソッドにて、さらにAのキーを含むBのデータを取得して、
AのデータとBのデータをforで回しながら、
キーが一致したらアップデートするというような処理を行うとした場合、
Bのデータがexecuteでデータを取得しているので、ガバナ制限に引っかかるといったことは
あるでしょうか。
上記が実装できない場合は、以下のように実装しようかと考えています。
Aのデータを取得して、finishメソッドで別のバッチを起動し、その際、AのscopeをBに渡す。
例
```
global List<sObject> scopeA;
global void execute(Database.BatchableContext BC, List<sObject> scope) {
scopeA = scope;
}
global void finish(Database.BatchableContext BC) {
BatchB batchB = new BatchB(scopeA);
Database.ExecuteBatch(batchB);
}
```
以下にて、ロケータでAを取得しAを更新するのは理解していますが、
http://tyoshikawa1106.hatenablog.com/entry/2015/02/15/182505
Aを取得した結果をBにいれる場合について
最適な方法を教えて頂ければ幸いです。
その際、Aというオブジェクトから取得したデータをBに突っ込むといったケースの実装につきまして、
まずはじめに、startメソッドでAのデータを取得したのち
executeメソッドにて、さらにAのキーを含むBのデータを取得して、
AのデータとBのデータをforで回しながら、
キーが一致したらアップデートするというような処理を行うとした場合、
Bのデータがexecuteでデータを取得しているので、ガバナ制限に引っかかるといったことは
あるでしょうか。
上記が実装できない場合は、以下のように実装しようかと考えています。
Aのデータを取得して、finishメソッドで別のバッチを起動し、その際、AのscopeをBに渡す。
例
```
global List<sObject> scopeA;
global void execute(Database.BatchableContext BC, List<sObject> scope) {
scopeA = scope;
}
global void finish(Database.BatchableContext BC) {
BatchB batchB = new BatchB(scopeA);
Database.ExecuteBatch(batchB);
}
```
以下にて、ロケータでAを取得しAを更新するのは理解していますが、
http://tyoshikawa1106.hatenablog.com/entry/2015/02/15/182505
Aを取得した結果をBにいれる場合について
最適な方法を教えて頂ければ幸いです。
更新用のリストを1つ用意して、forループ → 条件にマッチ → 更新用リストに追加 → ループ後にUpdate処理を実行という流れが望ましいと思います。
また、『finishメソッドで別のバッチを起動し、その際、AのscopeをBに渡す。』という方法ですが、Apexバッチでは繰り返し実行されるのはexecute処理のみとなっています。finishは最後に1回のみなので上記書き方の場合だとscopeAが毎回上書きされてしまうことになります。
例) バッチ処理の流れ
少し話がそれますが、finish処理で別のバッチ処理を呼び出すということ自体は問題ありません。
All Answers
更新用のリストを1つ用意して、forループ → 条件にマッチ → 更新用リストに追加 → ループ後にUpdate処理を実行という流れが望ましいと思います。
また、『finishメソッドで別のバッチを起動し、その際、AのscopeをBに渡す。』という方法ですが、Apexバッチでは繰り返し実行されるのはexecute処理のみとなっています。finishは最後に1回のみなので上記書き方の場合だとscopeAが毎回上書きされてしまうことになります。
例) バッチ処理の流れ
少し話がそれますが、finish処理で別のバッチ処理を呼び出すということ自体は問題ありません。
勉強になります。
>更新用のリストを1つ用意して、forループ → 条件にマッチ → 更新用リストに追加 → ループ後にUpdate処理を実行という流れが望ましいと思います。
はい、その認識はあります。
現在、以下のような実装をしてみました。
更新するものをまず、queryLocatorで取得しておいて(executeメソッドのscope変数)
executeメソッドでbデータを取得して、
キーが一致したらscopeを内容を書き換え
ループの外側の最後でupdateする形です。
パフォーマンスは悪そうですが、
それ以外にも、ガバナ制限にもかかりそうな気もしてはいます。
最適な方法あれば教えて頂ければ幸いです。