Шпаргалка по Apex CPU Time Limit

При разработке сложных решений с лихо закрученной бизнес логикой, которые появляются в результате dream-bruteforce-brainstorming(а) различных department-ов заказчика, нам, обычным разработчикам и админам, иногда приходится сталкиваться с такой вещью, как Apex CPU Time Limit.

  1. Согласно официальному ответу :
    для того, чтобы не сталкиваться с Apex CPU Time Limit Exceeded в процессе работы, необходимо учитывать следующие моменты данного лимита:
  • Лимит включает в себя почти все, что происходит на сервере, включая декларативные действия и инструменты, работающие в рамках одного Apex контекста - т.е. для всего исполняемого Apex кода и любых процессов, которые вызываются из этого кода (напрямую или косвенно), таких как процессы валидации, workflow, process builder processes, flow и т.д.

  • Лимит является общим и для вашего кода, и для кода certified managed packages. Для многих других видов лимитов у managed packages есть свои отдельные лимиты, но этот - одно из исключений. Заветные ~10 сек вы все-таки делите с другими пакетами. И тут проблема не столько в самих пакетах, сколько в пользователях, которые могут установить неоправданно много этих самых пакетов, с точки зрения здравого смысла, логики и требуемой функциональности.

  • Лимит относится к разряду статичных. Т.е. нет никаких workaround(ов), позволяющих каким-то образом увеличить данный лимит, будь то настройки самой организации в Setup, покупка дополнительных лицензий или даже специальный тарифный план с увеличенным CPU Time на транзакцию.

  • Лимит немедленно и полностью останавливает выполнение в рамках контекста как только достигнуто превышение.

  • Лимит, его нарушение, осуществляет roll-back всех успешных DML операций в рамках контекста.

  • Лимит НЕ учитывает время “ожидания на выполнение” на уровне базы данных для DML, SOQL, SOSL и время ожидания Apex callouts.

  1. Как не получить Apex CPU Time Limit Exceeded.
  • Используйте встроенные возможности Apex и обращений к базе данных.
    Вместо:

    Наверное, лучше обойтись таким вариантом:

    Т.е., по возможности, вынесите логику фильтрации записей, выполнения элементарных агрегирующих операций (SUM, AVG, COUNT) в сами запросы.

  • Используйте асинхронные операции там, где это возможно с точки зрения интерфейса / бизнес-логики / архитектуры решения. Особенно для “долгих” и/или непредсказуемо долгих операций: например, отправка email / mass email, создание “вспомогательных” записей в виде кастомных related объектов - первые кандидаты на подобную оптимизацию.

  • Рассмотрите возможность переноса логики содержащейся в инструментах автоматизации на уровень триггеров. Причем весь код лучше поместить в helper класс, гарантирующий “одноразовый запуск”, независимо от того, что могут “начудить” с количеством вызовов триггеров в одном контексте установленные managed packages и/или legacy код из разряда “так исторически сложилось”.

  • Используйте возможности dev console при анализе возникшей ошибки, а именно в данном случае особенно полезную вкладку Timeline:

И главное, при получении Apex CPU Time Limit Exceeded:
Keep calm!

3 Likes

как раз актуальная тема. Сижу ломаю голову над этой проблемой )))) Замучился. Причем выполняю операцию с Юзерами у которых одинаковые права. У одного все в порядке, все работает. У другого появляеться Apex CPU TIme limit

Спасибо большое. Очень полезно