第2回では、ガバナ制限を回避するため、複数レコードに対する一括処理などについて紹介しました。第3回では別のアプローチとして、非同期処理を利用する方法を解説します。ガバナ制限は、1回のリクエスト処理(ここでは、トランザクションと呼びます)に対して課されます。一連の処理を複数のトランザクションに分割できれば、ガバナ制限を回避しやすくなります。
Force.comには、メソッドを非同期で実行する機能があります。そして、非同期で実行されるメソッド(ここでは非同期メソッドと呼びます)は、新たなトランザクションとして扱われます。つまり、非同期メソッドを活用することでガバナ制限に引っ掛かりにくくなります。
メソッドを非同期で実行するには、リスト1のように「futureアノテーション」を宣言して呼び出します。すると、呼び出されたメソッドはいったんシステム内部のキューに格納され、システムリソースに空きが出たときに実行されます。
global class MyFutureClass {
@future
static void myMethod(List idList) {
// 非同期で実行するコード
}
}
ただし、非同期メソッドにも制限があるので注意が必要です。「1回のトランザクション内で実行は最大10回まで」「非同期メソッドの中で、さらに非同期メソッドを呼び出すことはできない」といったものです(表1)。
▽1回のトランザクション内で実行は最大10回まで |
▽Full Salesforceユーザーの場合には1ライセンス当たり、24時間で実行は200回まで(Customer Portalユーザーの場合、1ライセンス当たり100回まで) |
▽メソッドの引数は、プリミティブ型、あるいはプリミティブ型のListかCollectionのみを許可(sObjectは引数に取れない) |
▽Visualforceのコンストラクターからは実行できない |
▽戻り値を取れない |
▽実行順序は保証されない |
▽futureアノテーションを持つメソッドからPageReferenceのgetContent、 getContentAsPDFメソッドを呼び出せない |
▽futureアノテーションを持つメソッドから、futureアノテーションを持つ別のメソッドを呼び出せない。トリガーを経由する場合も同様 |
こうした制限があるので、大量のデータに対して複雑な処理を行おうとすると、非同期メソッドの活用だけではガバナ制限の回避が難しくなります。例えば、Insertトリガーは最大1000件(Spring '11バージョン)のレコードを受け取れるので、これを10個の非同期メソッドに分割すれば、1トランザクション当たり100件処理することができます。しかし、処理が複雑な場合には、たとえ100件であってもガバナ制限を回避できないケースが出てきます。
そこで次に、より大量のデータに対して複雑な処理を行うテクニックとして、「非同期処理をメールで呼び出す」「バッチ処理をオンライン処理から起動する」方法を紹介します。