問題
ある企業は、顧客に教育ビデオを視聴してもらうための推進計画を実施しました。顧客は数日間にわたりビデオを視聴することができ、その進捗は記録されます。動画をすべて視聴完了すると、顧客に報奨ポイントが付与されます。動画がSalesforceで完了としてマークされた際、外部のWebサービスを呼び出して、ユーザーにポイントを付与する必要があります。
開発者は、この要件をSalesforceのafter updateトリガー内で外部Webサービスへの呼び出しとして実装しました。しかし、実装後にSystem.CalloutExceptionが発生しています。このエラーを解消するために、開発者はどのような対応をすべきでしょうか。
- after update トリガーを before insert トリガーに置き換える。
- 外部 Web サービスと統合する REST サービスを作成する。
- 外部呼び出しを try-catch ブロックで囲み、例外を処理する。
- @future(callout=true)を使用して、コールアウトを非同期メソッドに移動する。
正解
- after update トリガーを before insert トリガーに置き換える。
- 外部 Web サービスと統合する REST サービスを作成する。
- 外部呼び出しを try-catch ブロックで囲み、例外を処理する。
- @future(callout=true)を使用して、コールアウトを非同期メソッドに移動する。
解説
問題文において「開発者がafter updateトリガー内で外部Webサービスへの呼び出しを実装した」という部分が、System.CalloutExceptionの発生の主な要因です。Salesforceでは、after updateトリガーの中でレコードが更新された直後の同期的なHTTPコールアウトは許可されておらず、これがエラーの原因となります。具体的には、レコードの更新というDML操作と同期的なコールアウトが一つのトランザクション内で同時に行われることは許されていません。
それぞれの選択肢の理由について説明します。
□ after update トリガーを before insert トリガーに置き換える。
これは不正解です。このエラーはトリガーのタイミング(after update または before insert)に関連しているわけではありません。また、動画が完了としてマークされるときにポイントを付与するため、before insert トリガーはこのシナリオには適していません。
□ 外部 Web サービスと統合する REST サービスを作成する。
これは不正解です。このエラーは、REST サービスの存在やその作成方法に関連しているわけではありません。エラーの原因はトリガー内での同期的なコールアウトに関連しています。
□ 外部呼び出しを try-catch ブロックで囲み、例外を処理する。
これは不正解です。例外をキャッチすることは良い実践ですが、それだけではSystem.CalloutExceptionの根本的な原因を解決しません。トリガー内での同期的なコールアウトが許可されていないため、このエラーが発生します。
□ @future(callout=true)を使用して、コールアウトを非同期メソッドに移動する。
これは正解です。Salesforceでは、トリガー内での同期的なコールアウトは許可されていません。そのため、非同期メソッドを使用してコールアウトを行う必要があります。@future(callout=true) アノテーションを使用することで、非同期的に外部サービスを呼び出すことができます。
コメント