本記事はSalesforce の実装中に 「You have uncommitted work pending.Please commit or rollback before calling out.」 というエラーメッセージに悩まされた時の備忘録です。
日本語のメッセージは「未確定の作業が保留中です。コールアウトを実行する前に確定またはロールバックしてください。」です。
エラー原因
このエラーは、1つのトランザクション内で DML(insert, update, delete など)処理を行った後に、外部コールアウトを行うと発生します。
開発において、APIをコールしてその値をオブジェクトに保存し、別のAPIをコールする・・・というケースもあるでしょうが、その処理はできないのです。
不便。
回避方法
パッと思いつく回避方法は以下の通り(ですが、保証はできかねます)。
トランザクションを分ける
一番無難な方法です。 例えばLWCからApexをコールし、その中でコールアウトを行う。 そのレスポンスの値を利用して、再度Apexを呼び、その中でコールアウトを行う。
といった具合です。
しかし、この実装の場合は一度フロントに二つ目のApex処理に必要なデータを返すことになります。そのため、重要なデータを扱う場合には推奨できません。
代わりに、一つ目のApex処理でオブジェクトに値を保持し、二つ目のApexでその値をSELECTして利用することで回避できます。 しかし、オブジェクトに適切な項目がない場合は新規に定義せざるを得ないので辛いです。
DML処理を最後に回す
Apex内でのコールアウト処理の後にDML処理を定義することで、この問題を回避することはできます。
しかし、ロジックの都合上、この実装が不適切な場合もあるのでご注意ください。
参考
- Salesforceナレッジ -「You have uncommitted work pending. Please commit or rollback before calling out」エラーについて
- Salesforceナレッジ - 「You have uncommitted work pending.Please commit or rollback before calling out. (未確定の作業が保留中です。コールアウトを実行する前に確定またはロールバックしてください。)」エラー
おわりに
Salesforce の開発はフラストレーションが溜まります。
コメント