Contents
はじめに
Salesforce開発をしていく上で切っても切り離せられないのが、ガバナ制限だ。
この制限に抵触すると、トランザクションの失敗やデータの不整合、ユーザーエクスペリエンスの悪化、
システム全体のパフォーマンス低下など、さまざまな問題が発生します。
そのため、Salesforceの開発では、これらの制限を意識しながら設計・実装を行い、
アプリケーションが安定して動作するようにすることが重要です。
何が言いたいかというと、実際の現場で働いていると、UT工程やST工程で「ガバナ制限に抵触しました」ということが起こって、悲惨なことが起きてしまったという経験は少なくないので、紹介したい。
ガバナ制限とは?
ガバナ制限:
Salesforceがプラットフォームの健全性を保つために設定しているリソースの使用制限のこと。
1つの組織やユーザーが過度にリソースを消費して他の組織に影響を与えないように、いくつかの制限を設けている。
要は、みんなが公平に使えるようにするための「お約束」となる。
これだけだと「なんで、こんな制限を設けているのか?」というのが分かりづらいので何か別のものに例えて説明しよう。
たとえば、みんなで遊んでいる公園で、一人だけがずーっとブランコを使っていたら、他の子たちはブランコで遊べなくなっちゃうと思います。
それと同じで、Salesforceという大きなコンピュータのおもちゃ箱でも、一人だけがたくさんのおもちゃ(リソース)を使うと、他の人が困ってしまいます。
だから、Salesforceでは「一人が使えるおもちゃの数を決めて」、みんなが楽しく遊べるようにしています。
これを「ガバナ制限」と呼ぶ。
「お約束(ガバナ制限)」を守ることで、みんながちゃんと順番に遊べて、壊れたり、遅くなったりしないようにしてすることができるようになる。
主なガバナ制限の種類
SOQL クエリの制限:
- 1トランザクションあたり最大100件のSOQLクエリ(通常のコンテキストで)。
- 1クエリで返されるレコードの最大数は50,000件。
DML 操作の制限:
- 1トランザクションあたり最大150件のDMLステートメント(insert、update、deleteなど)。
- 1回のDML操作で処理できるSObjectの数は最大10,000件。
CPU時間の制限:
- 1トランザクションでのApexコードの実行時間は最大10秒(通常のコンテキストで)。
ガバナ制限の他の例:
- 1トランザクションあたりの最大コールアウト数。
- 1トランザクションあたりのメソッドの再帰呼び出しの深さ。
- 1組織あたりのカスタム設定やカスタムメタデータの最大ストレージ。
ガバナ制限の目的
- システムの安定性: 複数のユーザーや組織が同時にSalesforceを使用しても、プラットフォームが安定して動作するようにする。
- 公平なリソース使用: 1つの組織がリソースを独占せず、すべての組織が公平にリソースを利用できるようにする。
- 効率的なコードの推奨: 開発者が効率的なコードを書けるようにし、不要なリソースの消費を抑える。
SOQL クエリの制限とDML 操作の制限に抵触する例をまとめてみた
▼ガバナ制限に抵触するコード
// SOQL クエリの制限に抵触(SOQLクエリをforルールの中で実行している)
for(Account thisAccount: [SELECT Id, Industry FROM Account LIMIT 150]) {
if(thisAccount.Industry == 'Technology') {
thisAccount.Is_Tech__c = true;
}
// DML 操作の制限(forループの中でDML操作(update)をしている)
update thisAccount;
}
上のコードは for ループの中でSOQLの発行、DML操作(update)を繰り返し実行しているため、ガバナー制限に達する可能性があります。
▼ガバナ制限に抵触しないように修正したコード
// SOQL クエリは for ループの外で一度だけ実行する
List<Account> accountList = [SELECT Id, Industry FROM Account LIMIT 150];
List<Account> accountsToUpdate = new List<Account>();
// for ループでクエリ結果を処理する
for(Account thisAccount : accountList) {
if(thisAccount.Industry == 'Technology') {
thisAccount.Is_Tech__c = true;
accountsToUpdate.add(thisAccount);
}
}
// まとめて更新する
if(!accountsToUpdate.isEmpty()) {
update accountsToUpdate;
}
SalesforceにはDMLステートメントの最大実行回数(1トランザクションあたり150回)があり、同期コンテキストではこれを超えるとエラーが発生する。
ガバナ制限に違反すると、例外がスローされ、そのトランザクションは失敗します。そのため、Salesforceで開発を行う際は、これらの制限を考慮しながら設計・実装することが重要です。
ガバナ制限に抵触することで何が問題があるか?
ガバナ制限に抵触することが問題となる理由は、Salesforceプラットフォーム上でのアプリケーションの信頼性、パフォーマンス、ユーザー体験に悪影響を与える可能性があるからです。
具体的には、以下のような問題が発生します。
1. トランザクションの失敗
- 例外がスローされる:
ガバナ制限に抵触すると、LimitException
などの例外がスローされ、現在実行中の
トランザクション(例えば、Apexコードの実行、バッチ処理、トリガーなど)が
即座に停止します。
この結果、そのトランザクション内での全ての処理がロールバックされ、データの更新や処理が完了しないまま終了します。 - データの不整合:
処理が途中で失敗しロールバックされるため、システム内のデータが期待した状態にならないことがあります。これにより、ユーザーがエラーに気づかずに操作を続けた場合、データの整合性が損なわれるリスクが生じます。
2. ユーザーエクスペリエンスの悪化
- エラー画面の表示:
ユーザーが操作を行った際にガバナ制限に引っかかると、エラー画面が表示され、
処理が停止します。
これにより、ユーザーは混乱し、業務の中断や手戻りが発生する可能性があります。 - 動作が遅くなる:
例えば、CPU時間制限に抵触する場合、アプリケーションの応答が遅くなり、
全体的な操作性が悪化します。
3. パフォーマンスの低下
- システム全体の負荷増加:
ガバナ制限に抵触しないように処理を分割する必要があるため、複数のトランザクションやバッチ処理をスケジューリングすることになります。
これにより、システムのパフォーマンスが低下し、他のトランザクションやプロセスにも影響を与える可能性があります。
4. 開発とメンテナンスのコスト増加
- 追加のコード修正が必要:
ガバナ制限に抵触しないようにコードを再設計したり、処理を最適化する必要があるため、
開発とメンテナンスのコストが増加します。
たとえば、DML操作やSOQLクエリをループの外に出す、バッチ処理を使用するなどの対策が
求められます。 - テストの難易度が上がる:
ガバナ制限に対応するためのコードは複雑になることがあり、その分テストやデバッグも
難しくなります。
5. スケーラビリティの制約
- システムの成長に対応できない:
ガバナ制限を考慮せずに設計されたシステムは、データ量やユーザー数が増えた際に
スケールしにくくなる可能性があります。
つまり、システムやアプリケーションの規模が大きくなっても、
動き続けることができないので、大きくしにくい。
これにより、ビジネスの成長に伴って発生するニーズに対応できないというリスクがあります。
まとめ
ガバナ制限に抵触すると、トランザクションの失敗やデータの不整合、
ユーザーエクスペリエンスの悪化、システム全体のパフォーマンス低下など、
さまざまな問題が発生します。
そのため、Salesforceの開発では、これらの制限を意識しながら設計・実装を行い、
アプリケーションが安定して動作するようにすることが重要です。
実際現場で、開発者としては作業している時は、
「ルールに抵触しないようにコーディングすればいいんでしょ?」という程度で、
なんでそのルールがあるのかというのを深く考えたことがなかった。
ただ、立場が変わり「このルールってなんであるんだっけ?」と理解していなかったので、
改めて学び直すと「チーム全体に迷惑がかかる。下手したら、さらに色々な人に迷惑がかかってしまう。」
ということがわかったので、学び直すって重要だなと思いました。
では、また次の記事でお会いしましょう。