Salesforce Platform постоянно совершенствует архитектуру автоматизации в соответствии с требованиями сложных бизнес-процессов. Предыдущие поколения — бизнес-правила и конструктор процессов — стали первоначальными шагами в логике под управлением событий, расширив возможности автоматизации для логики под управлением событий и расширив охват более широкого круга конструкторов.

Эта эволюция привела к созданию высокопроизводительной консолидированной архитектуры, основанной на двух взаимодополняющих компонентах: Триггеры потока, запущенного записью, и Apex. Этот документ предоставляет основу и рекомендации для принятия обоснованных решений при создании триггерных автоматов.

Поток Salesforce Flow - это мощный интерактивный инструмент автоматизации, позволяющий пользователям создавать сложные бизнес-процессы, окна и логику визуально посредством Flow Builder без написания кода. Он автоматизирует задачи, например, обновления данных, отправку сообщений эл. почты и руководство пользователями, предлагая гибкость посредством типов потоков окон (взаимодействие с пользователем) и запущенных потоков (запись/запланированные события).
Apex Salesforce Apex - это собственный объектно-ориентированный язык программирования для Salesforce Platform, подобный Java, используемый для создания настраиваемой бизнес-логики, автоматизации процессов и расширения базовых функций CRM за пределы декларативных инструментов.

Создание масштабируемой, обслуживаемой и производительной автоматизации, запущенной записью, на Salesforce Platform требует дисциплинированного подхода под руководством архитектуры. При выборе между Flow и Apex, а также при реализации каждого из них, руководствуйтесь четким набором принципов. Эти положения суммируют эти принципы и служат основополагающими правилами современного проектирования автоматизации.

  • Выберите нужный инструмент на основе плотности автоматизации объекта Salesforce.

    • Используйте поток, запущенный записью, для объектов Salesforce для автоматизации низкой плотности.

    • Дополните логику потока, запущенного записью, вызываемым Apex для автоматизации средней плотности.

    • Используйте триггеры Apex для объектов Salesforce для автоматизации высокой плотности.

  • Соблюдайте осторожность при запуске асинхронных процессов.
    Это правило применяется вне зависимости от того, вызываете ли вы асинхронные процессы в потоке, запущенном записью, или ставите в очередь задание из Apex. Хотя такая схема может быть соблазнительной для разгрузки работы, она может ввести сложные сценарии обработки ошибок и повысить риск достижения губернаторских ограничений.

  • Используйте одну точку входа на объект Salesforce.
    Для данного объекта Salesforce используйте один механизм в качестве отправной точки автоматизации. Рекомендуем избегать смешивания триггеров Flow и Apex в качестве точек входа для одного объекта.

Flow и Apex имеют общий набор фундаментальных возможностей. Каждый инструмент может запрашивать записи, выполнять условную логику, назначать переменные и выполнять операции DML, например, создавать, обновлять и удалять записи, в определенной последовательности для выполнения.

Однако это функциональное наложение не означает, что инструменты являются взаимозаменяемыми. Архитектурный выбор зависит не от того, может ли задача быть выполнена, а от того_, как_ она выполнена и каковы долгосрочные последствия для производительности, масштабируемости и ремонтопригодности. Flow преуспевает в декларативной четкости и скорости внедрения для простых процессов, а Apex обеспечивает гранулированный контроль и исходную мощность, необходимую для сложных решений.

Плотность автоматизации — это нагрузка на определенный объект Salesforce. Он служит эвристическим для определения оптимальной реализации объекта. С ростом плотности автоматизации вероятность нарушения транзакционных ограничений увеличивается.

Вычисление плотности автоматизации посредством проверки трех определенных измерений объема и сложности:

  • Количество автоматизации: Исходное количество уникальных записей метаданных автоматизации (потоки, действия триггера и прочие), выполняемых во время одного события языка манипуляции данными (DML).

  • Объем записи: Записи на транзакцию, обработанные посредством загрузок API или тяжелой пакетной обработки, где производительность становится критической.

  • Разрастание зависимости: Мера последующих операций DML, запущенных первичной операцией CRUD. Он определяет глубину графика, где одно обновление каскадируется в обновления связанных объектов (например, обращение → организация → контакт → настраиваемая сводка).

Измерения плотности автоматизации

По мере расширения масштабов и сложности приложения Salesforce рекомендуем использовать одну основную точку входа — поток, запущенный записью, или триггеры Apex. Избегайте разделения автоматизаций в нескольких механизмах в одном объекте Salesforce, поскольку это приводит к плохой ремонтопригодности и фрагментации управления.

Используйте эту матрицу для определения обязательного архитектурного стандарта для объекта Salesforce.

  • Поток, запущенный записью, является предпочтительным решением для низкой плотности автоматизации. Он предлагает баланс мощности и доступности, который идеально подходит для автоматизации, простой и независимой друг от друга.

  • Гибридная схема (поток, инициированный записью, с вызываемым Apex) является эффективным и обслуживаемым вариантом для автоматизации средней плотности с усложняющейся системой. Эта схема дает возможность группам поддерживать упорядоченную хореографию в декларативном потоке, делегируя Apex компьютерные операции, балансируя между доступностью и производительностью.

  • Триггеры Apex являются необходимыми структурными элементами прочной архитектурной основы для поддержки высокоплотной автоматизации. Производительность, детализированный контроль, а также объектно-ориентированная абстракция и полиморфизм Apex лучше подходят для управления сложностью и масштабностью этих сценариев.

Уровень плотности Количество автоматизации Объем данных (пакетный размер) Разрастание зависимости Архитектурный стандарт
Низкий < 15
Автоматизация
Стандартный
Взаимодействия пользовательского интерфейса под управлением пользователя или небольшие загрузки API (1-200 записей)
Дискретный
Автономная логика. Операции DML 0-1 в нисходящем направлении для одного объекта или связанного объекта.
Поток, запущенный записью
Средний 15–30
Автоматизация
Модерирование
Стандартная пакетная обработка (с логикой, требующей тщательного пакетирования)
Связано
«Родитель/ребенок» обновляет 2-4 операции DML в нисходящем направлении. Риск рекурсии
Гибридная схема
Flow + вызываемый Apex
Высокий > 30
Автоматизация
Высокий
Большие объемы данных с пакетной загрузкой API (2 000 – 10 000+ записей)
Сложный и рекурсивный
График глубокой зависимости (5+ операции DML в нисходящем направлении). Риск треугольных циклов рекурсии
Инфраструктура метаданных триггера Apex
Реальные архитектурные решения требуют взвешивания всех измерений плотности автоматизации вместе. Учитывайте потенциальную будущую область при выборе механизма автоматизации для данного объекта Salesforce.

Кроме того, учитывайте общее ежедневное количество операций DML, поскольку Salesforce применяет совместное управление ресурсами в среде с несколькими клиентами и ограничениями управления, чтобы предотвратить монополизацию общедоступных ресурсов автоматизацией. Объекты Salesforce с большим ежедневным объемом DML требуют тщательного выбора автоматизации. Например, асинхронные ограничения времени процессора (60 000 мс) и размера кучи (12 Мб) превышают синхронные ограничения. Кроме того, единые 24-часовые ограничения для асинхронных выполнений, рассчитанные как 250 000, или 200-кратные лицензии пользователя, требуют учета общего ежедневного DML в архитектурном проекте во избежание исключений среды выполнения.

Поток, запущенный записью, является главным декларативным инструментом платформы для автоматизации, запущенной записью. Простота использования потока и встроенные гарантии платформы позволяют рабочим группам легко создавать масштабируемые и надежные решения. Это идеальный выбор для большинства рабочих групп, создающих решения на Salesforce Platform.

Apex - это собственный, сильно типизированный, объектно-ориентированный язык программирования платформы. Используйте Apex для объектов Salesforce с высокой плотностью автоматизации, а также для сценариев использования, требующих высокой производительности, сложной логики или детального контроля над транзакциями.

Чтобы помочь в процессе принятия решений, эта матрица предоставляет прямое сравнение Flow и Apex по ключевым архитектурным возможностям.

Возможности Поток, запущенный записью Триггер Apex
Скорость доставки и обслуживания Рекомендуется
Визуальный пользовательский интерфейс Flow Builder позволяет администраторам и другим декларативным конструкторам создавать и изменять автоматизацию быстрее, чем написание, тестирование и развертывание кода Apex. Этот интерфейс предоставляет возможность более широкому кругу участников рабочей группы предоставлять бизнес-ценности и уменьшает зависимость от специализированных ресурсов разработчика для выполнения простых задач.
Требует опыта
Apex требуются разработчики ПО с соответствующими навыками для внедрения, тестирования и обслуживания кода.
Модульность Доступно
Потоки, запущенные записью, являются модульными по умолчанию. Вместо монолитной логики рабочие группы создают отдельные потоки под определенные требования и хореографируют их вместе посредством проводника по триггерам потока. Эта модульность позволяет изолированно изменять и просто расширять, значительно снижая долгосрочную стоимость владения.
Доступно
По конструкции Apex разделен на функциональные модули. Каждый класс Apex предназначен для реализации единого модуля функций.
Доступность и управление Рекомендуется
Визуальная природа потока предоставляет интуитивное представление бизнес-логики. Проводник по триггерам потока предоставляет консолидированное представление всех потоков в объекте, упрощая понимание, управление и устранение неполадок архитекторами и администраторами без чтения кода.
Требует опыта
Использование инфраструктуры метаданных для систематизации триггеров выгодно, но Apex требует наличия дисциплинированной группы разработчиков для поддержания систематизации и обслуживания кода.
Высокопроизводительная пакетная обработка данных Не рекомендуется
Существует повышенный риск достижения губернаторских ограничений при работе со сложной логикой или большими объемами данных.
Рекомендуется
Код Apex выполняется ближе к базовым службам платформы и предлагает разработчикам расширенный контроль над оптимизацией запросов, обработкой данных и алгоритмической эффективностью. Это приводит к лучшей производительности и масштабу, особенно в сложных сценариях, связанных с большими объемами данных.
Надежная логика и структуры данных Доступно
Элемент трансформации потока может помочь в выполнении некоторых сложных задач обработки. Однако, в потоке отсутствуют собственные структуры данных «Карта» и «Задать», что делает обработку сложных данных громоздкой и неэффективной с компьютерной точки зрения.
Рекомендуется
Apex предоставляет полный доступ к циклам «Карта», «Задать» и «Программирование» для высокоэффективных, безопасных для пакетного обработки данных манипуляций. Являясь полнофункциональным языком программирования, Apex также предоставляет доступ к сложным логическим конструкциям, структурам данных и схемам проектирования, которые могут помочь в решении сложных бизнес-задач обслуживаемым и эффективным способом. Apex содержит богатую стандартную библиотеку расширенных функций (например, BusinessHours, Crypto), в данный момент недоступную в декларативных инструментах.
Управление транзакциями Недоступно
Поток не предоставляет доступа к `Database.savepoint`, `Database.rollback` или частично успешным операциям DML для частичных обязательств транзакций или откатов.
Доступно
Apex предоставляет полный, детальный контроль над целостностью транзакций и сложными сценариями восстановления ошибок.
Распространение электронной почты Рекомендуется
Отправка предварительно настроенных электронных предупреждений из потока, запущенного записью, проста и масштабируема. Настраиваемые электронные предупреждения могут быть созданы и распространены во время выполнения. Настраиваемые сообщения эл. почты подлежат ежедневному ограничению отправки.
Доступно
Apex может создавать и отправлять настраиваемые сообщения эл. почты. На все сообщения эл. почты, отправленные из Apex, распространяются ежедневные ограничения отправки.
Применение гарантий платформы Рекомендуется
Поток содержит встроенные средства защиты, например, автоматическое пакетирование и автоматические повторы. Эти гарантии увеличивают скорость до значения и предотвращают ошибки производительности, которые в противном случае требуют сложного ручного кодирования.
Требуется ручное внедрение
Такие гарантии, как пакетирование, должны быть четко закодированы (например, управление коллекциями и избежание SOQL внутри циклов). Автоматические попытки не являются нативными для триггеров и требуют сложной настраиваемой логики для внедрения.
Асинхронная обработка Доступно
Поток предлагает простые механизмы для автоматизации, требующие отдельной транзакции в асинхронном пути. Эти автоматизации подлежат ежедневному ограничению.
Доступно
Apex включает полный контроль посредством сбора данных об изменении и событий в очереди, которые обрабатываются отцепленным подписчиком триггера.
Запланированная обработка Рекомендуется
Запланированные пути потока предоставляют уникальную и мощную возможность планирования (например, «пожар за 3 дня до даты закрытия»). Эта возможность включает автоматическую отмену и повторное планирование при изменении данных записи. Эти автоматизации подлежат ежедневному ограничению.
Недоступно
Триггер Apex не может нативно запланировать временное событие, связанное с записью, с автоматической отменой. Пока запланированный Apex существует, это принципиально другой механизм, который выполняется в определенное время и не запланирован во время обработки отдельной записи как части триггера.
Заказ и хореография Доступно
Проводник по триггерам потока позволяет администраторам определить относительный порядок выполнения для нескольких потоков в одном объекте.
Доступно
Инфраструктура триггеров предоставляет детальный контроль над точным порядком автоматизации.
Обновления полей одинаковой записи Доступно (до сохранения)
Поток, запущенный записью, является наиболее эффективным декларативным параметром для обновления запускающей записи до первичного обязательства DML.
Доступно (до сохранения)
Apex предоставляет предложение наивысшей производительности с минимальными накладными расходами.
Cross-obъект CRUD Доступно (после сохранения)
Поток подходит для простых, несложных операций DML кросс-объекта.
Доступно (после сохранения)
Apex предоставляет превосходный контроль над дедупликацией, обработкой ошибок и производительностью для операций DML кросс-объектов.
Дублирование дорогостоящих вычислений Доступно
Поток успешно удаляет избыточные запросы и операторы DML посредством автоматического пакетирования. Однако, состояние не может быть кэшировано или общедоступно между разными триггерами потока или в нескольких вызовах одного потока в одной транзакции. Это ограничение может стать важным в экстремальных сценариях производительности.
Рекомендуется
Apex предоставляет механизмы дублирования дорогостоящих операций. Разработчики могут использовать транзакционное кэширование посредством статических свойств и переменных, а также кэширование на уровне платформы посредством кэша платформы для хранения и повторного использования данных. Эти методы важны для сокращения потребления транзакционных контролирующих ограничений, например, запросов SOQL, и обеспечения высокой производительности и масштабируемости.
Обработка настраиваемых ошибок Доступно
Элемент CustomError может блокировать операцию сохранения и отображать сообщение пользователю.
Рекомендуется
Метод addError() предоставляет гибкие сообщения об ошибках на уровне поля и условных ошибках.

Данная таблица содержит общие рекомендации по общим сценариям использования, в зависимости от представленных возможностей. В конечном счете, вы учтёте дополнительные рекомендации, чтобы они лучше соответствовали вашим сценариям, например, включенным в раздел «Связанные рекомендации» этого документа. Там вы узнаете больше о том, когда определенное сочетание Flow и Apex предоставляет лучший подход.

Способ использования Описание Лучше всего Обоснование
Высокопроизводительная пакетная обработка Любая автоматизация, которая должна эффективно обрабатывать тысячи записей Apex Apex предоставляет обогащенные API для взаимодействия с платформой и для исходной скорости.
Сложная обработка данных Сценарии, требующие расширенной манипуляции данными Apex Apex предоставляет структуры данных, например, Map и Set, которые недоступны в потоке, и могут быть критически важными для написания производительного пакетного кода.
Транзакционный контроль Механизмы управления, например, точки сохранения, откаты и частичные обязательства Apex Apex предоставляет доступ к таким механизмам, как Database.savepoint и Database.rollback, а также имеет возможность обработки частично успешных операций DML.
Сложная настраиваемая проверка Проверка данных в нескольких полях записи Apex Хотя поток может предотвратить сохранение посредством элемента `CustomError`, он недоступен во всех типах потоков, включая подпотоки. Метод Apex addError() предоставляет несколько полей сообщений об ошибках, которые можно добавить в запись в любое время во время обработки триггера.
Умеренно сложная логика в простом процессе Манипулирование логикой и данными средней сложности, упрощенное стандартной библиотекой расширенных функций, выполняемое в рамках несложного процесса Flow + Apex Поток, запущенный записью, действует как уровень оркестрации, в то время как операции высокой сложности инкапсулированы в вызываемый Apex.
Простая или умеренно сложная логика Манипулирование данными низкой и средней сложности с обновлениями триггеров как основного, так и связанного объекта данных Поток Поток обычно является вариантом перехода, поскольку он основан на декларативной модели, которая делает его доступным как для администраторов, так и для разработчиков.
Уведомления и исходящие сообщения Отправка исходящих сообщений эл. почты и сообщений Поток Поток упрощает и масштабирует отправку электронных предупреждений и исходящих сообщений об изменениях записей.
Запланированная обработка Автоматизация на будущую динамическую дату (например, за 3 дня до даты закрытия) Поток Запланированные пути предоставляют уникальную силу потоку, поскольку платформа автоматически обрабатывает планирование, отмену и перепланирование этих путей, если данные записи меняются.

Масштабируемость - это важная рекомендация при создании внедрения. Когда бизнес-логика автоматизации, запущенной записью, становится сложной, длительной или включает большие объемы данных, базовые контролирующие ограничения Salesforce Platform становятся архитектурным ограничением. Такие операции, как пакетные обновления данных, сложные выноски API или тяжелые вычисления увеличивают риск нарушения ограничений, например, общее время процессора или количество операторов DML в одной транзакции базы данных. Ошибка синхронного триггера из-за исключения ограничения приведет к откату всей транзакции сохранения пользователя, что приведет к плохой работе пользователя и потенциальной потере данных. Этот неотъемлемый риск требует наличия архитектурной схемы для разгрузки сложных работ.

Асинхронная автоматизация становится в данном случае важной. Используя асинхронные механизмы, архитекторы могут эффективно отделить долгосрочную или крупномасштабную работу от основной синхронной транзакции сохранения записей. Быстрое и надежное сохранение, в то время как тяжелая обработка делегируется отдельной управляемой платформой транзакции, которая выполняется позже. Разделение улучшает стабильность, предотвращает сбои транзакций и важно для создания масштабируемых корпоративных приложений. Платформа предлагает несколько специализированных инструментов для этого, каждый с определенными преимуществами и преимуществами относительно надежности, объема и сложности.

Путь «Выполнить асинхронно» в потоке, запущенном записью, предоставляет простейший механизм для асинхронной логики «выполнить и забыть». Этот путь выполняется в отдельной транзакции после успешного подтверждения исходной транзакции сохранения записи в базе данных.

  • Идеальный сценарий использования: Это хорошо подходит для задач, не требующих немедленного выполнения или настраиваемой обработки ошибок. Например, отправка электронного уведомления, создание дополнительной задачи или выполнение простого вызова внешней системы.

  • Ограничения: Этот механизм использует те же ежедневные контролирующие ограничения, что и другие асинхронные сеансы потока. Он не предназначен для экстремально массовой обработки.

Сбор данных об изменении (CDC) - это высокопроизводительная, масштабируемая и устойчивая схема обработки асинхронной логики, инициированная рекордным изменением массовых сценариев. В этой модели единственной обязанностью триггера является синхронное сохранение записи. Потом платформа публикует подробное сообщение о событии, содержащее изменения записи в шине массовых событий. Отдельный выделенный триггер Apex подписывается на это событие изменений. Он выполняет сложную, длительную или асинхронную работу.

  • Польза: Эта схема отделяет асинхронный процесс от первичной транзакции пользователя. Сбой в асинхронной обработке не приведет к откату сохранения записи пользователя. Шаблон также предоставляет долговечный поток событий, который могут использовать несколько внутренних подписчиков или внешних систем, а события могут проигрываться до 72 часов, обеспечивая высокую устойчивость.

  • Ограничения: Сообщения о событиях CDC не содержат предыдущее состояние записи, аналог Trigger.oldMap Apex. Полезная нагрузка события содержит новые значения полей, но не значения, с которых они изменились. Это затрудняет внедрение логики на основе определенного перехода в состояние (например, выполнение только при изменении Status__c с «Ожидание» на «Утверждено»). Это можно смягчить, запросив журнал поля объекта в подписчике события, но это добавляет сложности процессу, и отслеживание журнала поля может быть недоступно для определенного поля интереса. Это может ограничить типы автоматизации, которые можно выгрузить в CDC.

По умолчанию CDC может быть включен не более чем в пяти объектах Salesforce. Организации, которым требуется больше, могут приобрести дополнительную лицензию, которая снимет это ограничение и увеличит распределение доставки событий.

Постановка задания Apex в очередь напрямую из триггера должна считаться рискованной схемой, используемой только при необходимости управления Apex (например, для сложной логики или настраиваемых механизмов повторных попыток), а CDC не является жизнеспособным вариантом.

Если требуется Queueable Apex, внедрение должно содержать надлежащие гарантии:

  • Ограничение проверок: Код должен проверить количество заданий, уже поставленных в очередь в транзакции, прежде чем пытаться добавить еще одно.

  • Context Awareness: Код должен определить, выполняется ли он в асинхронном контексте, например, пакетное задание (System.isBatch()), и изменить свой алгоритм, чтобы соответствовать более строгому ограничению одной операции в этом контексте.

Вызов асинхронного Apex из синхронного триггера создает риски стабильности. Чтобы предотвратить влияние на уровне организации (например, превышение ограничений), эта схема требует тщательного проектирования и тестирования.

  • Ежедневное ограничение для асинхронных выполнений Apex (Batch, Queueable, @Future) используется в организации (обычно 250 000 или расчет на основе лицензий пользователя). Пакетная загрузка данных 20 000 записей приведет к выполнению триггера фрагментами по 200, что приведет к 100 отдельным вызовам триггера, что еще больше, если размер пакета меньше 200 записей. Если каждый вызов попадает в очередь на асинхронное задание, может быть израсходована значительная часть ежедневного ограничения от одной загрузки данных. Это потребление может потенциально привести к голоду других важных бизнес-процессов асинхронных ресурсов.

  • Границы очереди на рабочие места кардинально отличаются в зависимости от контекста. В триггере, запущенном действием пользователя в пользовательском интерфейсе (синхронная транзакция), можно создать до 50 заданий в очереди. Однако, из триггера, запущенного посредством метода execute класса Batch Apex — асинхронной транзакции — в очередь может быть поставлено только одно задание. Неучет этой разницы является распространенным и критическим моментом сбоя, приводящим к ошибкам LimitException во время больших операций над данными.

  • Вызов Schedulable Apex (System.schedule) или Batch Apex (Database.executeBatch) напрямую из контекста триггера является антипаттерном. Эти методы не предназначены для вызова из контекста триггера. Это приведет к быстрому расходованию асинхронного распределения Apex, что приведет к ограничению исключений.

Каждый асинхронный механизм имеет определенные компромиссы относительно производительности, контролирующих ограничений и надежности. Используйте это дерево решений в качестве руководства, чтобы помочь вам сориентироваться в этих параметрах и выбрать правильный механизм для вашего сценария использования.

Дерево решений по асинхронным схемам

Как видно из блок-схемы, когда вы столкнулись с массовыми операциями DML, но не можете использовать сбор данных об изменении (возможно, из-за ограничений объектов), лучший архитектурный выбор часто - полностью избежать процесса, вызываемого триггером.

Рекомендуем использовать запланированный процесс. Это может быть либо запланированный поток, либо запланированный Apex. Обязательные действия:

  1. Выполните простое недорогое обновление в синхронном триггере. Например, задайте полю Status__c значение «Ожидание обработки» или вставьте недорогую связанную запись (например, сообщение Chatter), чтобы указать, что запись нуждается в обработке.

  2. Создайте запланированное задание, запланированный поток или запланированный Apex, которое выполняется периодически, например, каждые 15 минут или каждый час.

  3. Выполните запрос запланированного задания для всех записей в состоянии ожидания, выполните сложную логику в управляемом контексте больших объемов, а потом обновите записи в соответствии с обработанными.

Эта схема полностью отделяет тяжелую обработку от синхронного сохранения пользователя, не подчиняется ограничению одного задания на транзакцию триггерного пакета и предоставляет высокомасштабируемое и управляемое решение для требований не в реальном времени.

Если задержка запланированного задания неприемлема для бизнес-требований, а вы все еще ограничены в использовании CDC или триггера в очереди, это указывает на значительное архитектурное несоответствие. На этом этапе необходимо рассмотреть разные механизмы. Повторная оценка базовой схемы приложения может привести к определенным выводам, например:

  • Приобретение надстройки для удаления ограничений объектов CDC.

  • Фундаментально оспаривая бизнес-требование для определения, является ли обработка в близком к реальному режиме времени действительно «обязательной» или задержка запланированного задания является приемлемым компромиссом для стабильности платформы.

Уровень сложности внедрения является частью общей стоимости владения решением, а также его способностью адаптироваться к изменяющимся бизнес-требованиям. Сложность может повлиять на любую реализацию, если не соблюдать рекомендации. В разделе «Связанные рекомендации» данного документа содержатся рекомендации по уменьшению сложности решения, включая следующие схемы:

  • Гибридная схема: Вызываемый Apex для сложной логики в потоке

  • Использование инфраструктуры метаданных для триггеров Apex

  • Мегапотоки по сравнению с Несколько потоков

Документация так же важна, как и сама автоматизация. Он не только обеспечивает обслуживаемость, но и является критически важным для инструментов на основе искусственного интеллекта и агентов. Документация помогает понять бизнес-процессы и управлять ими.

В потоке

  • Установите последовательное правило наименования для всех элементов и переменных.

  • Используйте поле «Описание» для потока, чтобы объяснить его общую цель, критерии запуска и предполагаемый результат.

  • Используйте поле «Описание» для каждого отдельного элемента (например, Get Records, Action, Transform). Эта практика - лучший способ передачи намерения. Это особенно важно для вызываемых действий и подпотоков, где описание является основным местом для объяснения сложной логики, выполняемой действием.

В Apex

  • Комментируйте код четко, чтобы объяснить, почему ваша логика, а не только что.

  • При использовании инфраструктуры под управлением метаданных убедитесь, что записи метаданных содержат и заполняют поле «Описание», чтобы объяснить, что делает каждый класс средства обработки и когда он должен выполняться.

DevOps и контроль источников являются частью зрелого жизненного цикла разработки. Всегда используйте инструмент контроля источников, например, Git для проектов Salesforce. И классы Apex, и потоки Salesforce - это метаданные, определяющие вашу бизнес-логику, и они должны быть версией и управляться.

В контексте управления автоматизацией, запущенной записью, современные ожидаемые продажи DevOps предоставляют важные преимущества.

  • Автоматические проверки качества: Такие инструменты, как Salesforce Code Analyzer, могут быть настроены на автоматическое выполнение в ожидаемых продажах. Статический анализ может обнаружить проблемные закономерности в обоих инструментах автоматизации до их внедрения, обозначив такие проблемы, как неэффективные элементы Get Records в цикле потока или SOQL запросы в цикле Apex for, которые являются распространенными причинами ухудшения производительности.

  • Предотвращение регрессии: По мере роста плотности автоматизации переход на один класс Flow или Apex может привести к непредвиденным последствиям для других автоматизаций этого же объекта. Надежная стратегия тестирования DevOps, когда автоматические тесты Apex выполняются против любых предлагаемых изменений, - самый надежный способ обеспечить, чтобы новая версия Flow не нарушила существующую логику Apex (и наоборот).

  • Сотрудничество и доступность: Контроль источников - это "единый источник истины". Он позволяет администраторам и разработчикам работать над автоматизацией для одного объекта параллельно. Это также дает бесценный контрольный журнал: когда производственный процесс нарушается, вы мгновенно видите, кто изменил автоматизацию, когда они изменили ее и — посредством сообщений о приверженности — почему они изменили ее.

Для рабочих групп со смешанным составом администраторов и разработчиков DevOps Center предоставляет объединенный интерфейс, помогающий организовать все эти этапы, делая масштабируемый процесс разработки на основе контроля источников доступным всем участникам рабочей группы.

Эта совмещенная дисциплина документации и DevOps обеспечивает долгосрочную работоспособность и обслуживание вашей организации, что принесет пользу каждому архитектору и администратору, которые следуют за вами.

Руководство по принятию решения выше лучше использовать перед планированием внедрения. Он направлен на то, чтобы помочь вам выбрать лучший продукт для ваших способов использования. После выбора продукта важно понимать существующие рекомендации по внедрению.

Принцип «Один инструмент на объект» является важным для управления автоматизацией высокой плотности, но не интерпретируйте его как двоичный выбор между чисто декларативным или чисто программным стеком. Более эффективная и обслуживаемая архитектурная схема использует гибридную модель: позиционирование потока, запущенного записью, в качестве слоя оркестрации, инкапсулируя высокосложные операции в вызываемом Apex.

Диаграмма гибридной схемы

Поток, запущенный записью, служит уровнем оркестрации для бизнес-процесса. Он отвечает за критерии входа и контекст выполнения (какие и когда). Сохраняя логику принятия решений и маршрутизацию в этом слое, топология процесса архитектуры остается прозрачной и управляемой посредством проводника по триггерам потока, предотвращая скрытие критической бизнес-логики в коде.

Одним из распространенных примеров сложного компонента является внедрение расчетов соглашения об уровне обслуживания (SLA) для записей обращений. Поскольку объект BusinessHours и связанная с ним логика — важная для точных вычислений, исключающих нерабочие часы и праздники, — недоступны в потоке нативно, используется выделенный класс Apex. Этот класс, часто называемый чем-то вроде ServiceLevelAgreementCalculator, разработан с помощью одного статического метода с аннотацией к @InvocableMethod для расчета затраченных часов работы, определения значения SLA «В пределах цели» или «Нарушено» и возврата структурированного вывода. Этот подход инкапсулирует сложную высокопроизводительную логику в Apex, позволяя без труда выполнять ее и интегрировать в декларативный слой оркестрации потока, запущенного записью.

После определения класса ServiceLevelAgreementCalculator Apex он доступен для использования в потоке, запущенном записью:

Эта тенденция свидетельствует о строгом разделении озабоченностей. Декларативный слой используется для управления жизненным циклом транзакций и оркестрации, в то время как код используется для сверхсложного выполнения. Рассматривая код как функциональную служебную программу, а не как основу, мы балансируем производительность и обслуживаемость.

Модульность: Решение сводиться от единственности использования Apex или Flow для всего процесса. Вместо этого, архитектура инкапсулирует сложную логику в отдельные, безопасные для пакетирования и независимо тестируемые единицы. Эти блоки функционируют как многоразовые компоненты, израсходованные декларативным слоем, обеспечивая автоматизацию весов без усложнения архитектурного дизайна.

Многоразовость: Логика отделена от события триггера. Продуманная единица кода (например, InvocableMethod) пишется один раз, но используется в нескольких точках входа: Потоки, запущенные записью, потоки окон или внешние интеграции. Это повторное использование кода исключает избыточную разработку.

Обслуживаемость: Логика процесса остается видимой и управляемой в декларативном потоке. Эта централизация значительно уменьшает накладные расходы на отладку и обеспечивает детерминистский и прозрачный порядок выполнения системы.

Хотя гибридная модель использования вызываемого Apex из потока мощна, она не является универсальным подходом. Архитекторы должны знать о конкретных ограничениях и компромиссах, прежде чем брать на себя обязательства по гибридному решению.

  • Нет поддержки перед сохранением: Это самое важное ограничение. Вызываемые действия доступны только в контексте после сохранения (потоки для действий и связанных записей). Они не могут использоваться в высокопроизводительном контексте перед сохранением (потоки для быстрых обновлений полей). Поэтому данная схема не может использоваться для делегирования обновлений полей одинаковой записи. Выполните высокопроизводительную работу с помощью собственных элементов потока в потоке перед сохранением или в триггере Apex перед контекстом.

  • Нет поддержки после удаления: Поток, запущенный записью, в настоящее время не поддерживает контекст после отмены удаления. Если у объекта Salesforce есть бизнес-требование к выполнению автоматизации при восстановлении записи из корзины, триггер Apex является единственным решением.

  • Производительность накладных расходов в массовых сценариях: Переход от среды выполнения потока к среде выполнения Apex не является нулевой операцией. Хотя в целом процесс перехода к вызываемому действию из среды выполнения потока выполняется не так быстро, как собственное выполнение, которое полностью не выходит за пределы триггера Apex. Для большинства автоматизаций средней плотности эти микронакладные расходы являются ничтожным и стоящим компромиссом в плане повышения доступности. Однако для экстремальных высокопроизводительных массовых сценариев преимущество в скорости вычисления будет у чистой инфраструктуры Apex.

Хотя эвристический подход к плотности автоматизации предоставляет окончательное руководство для новой архитектуры greenfield, реальность корпоративных сред Salesforce часто более нюансирована. В зрелых организациях часто встречаются потоки, запущенные записью, и триггеры Apex, работающие в одном объекте Salesforce. Этот сценарий отличается от гибридной схемы, описанной ранее: здесь потоки и триггеры Apex не связаны и не рассчитаны на совместную работу.

Такое сосуществование часто является результатом развивающихся возможностей платформы или устаревшей технической задолженности. Хотя это терпимое операционное состояние, архитекторы должны относиться к нему как к вычисленному компромиссу, а не как к конечному состоянию.

Фрагментарная оркестрация приводит к значительному управлению и обслуживанию, что делает разработку, тестирование и обработку инцидентов разрозненными и сложными. Это приводит к увеличению времени до принятия решения (TTR) и усложнению работы.

  • Для новых объектов Salesforce придерживайтесь принципа плотности автоматизации в качестве основного руководства.

  • Для существующих объектов Salesforce с гибридным выбросом и двойным триггером Apex и точками входа потока, запущенного записью, оцените плотность, а потом создайте архитектора для реорганизации к поддерживаемому гибридному состоянию.

    • Для низкой плотности рефактор Apex инициирует потоки, запущенные записью, и определяет порядок выполнения, приводя их к единой точке входа автоматизации.

    • Для средней плотности сложные мегапотоки рефактора превращаются в поднабор потоков с соответствующим порядком выполнения. Введите триггеры Apex только при крайней необходимости, например, для поддержки после восстановления контекста.

    • Для высокой плотности отдайте предпочтение внедрению триггеров Apex.

По мере взросления бизнес-процессов организации на Salesforce Platform объем и сложность автоматизации, запущенной записью, неизбежно возрастают. Фундаментальной рекомендацией является сохранение одного триггера Apex на объект Salesforce. Это правило важно, поскольку платформа не гарантирует порядок выполнения нескольких триггеров для одного объекта для одного события. Это ограничение может привести к недетерминистскому поведению, условиям гонки и трудно отладимым проблемам.

Однако соблюдение принципа единого триггера ставит архитектурную задачу: как управлять и систематизировать всю бизнес-логику, вызываемую из этой единой точки входа, на устойчивой и масштабируемой основе.

Первой эволюцией этой архитектуры стала схема средства обработки триггеров Classic. При таком подходе один триггер Apex делегирует всю логику соответствующему классу средства обработки (например, OpportunityTriggerHandler). Этот метод отделяет логику от файла триггера и предоставляет разработчикам детерминистский контроль над порядком выполнения в методах класса средства обработки (например, afterInsert()).

Несмотря на улучшение, эта схема часто приводит к монолитным классам обработчика. Со временем, по мере добавления дополнительных бизнес-требований, класс становится большим, сложным в управлении и трудно тестировать изолированно. Порядок выполнения всех отдельных процессов жестко запрограммирован в одном методе, что делает класс подверженным конфликтам слияния, значительно повышая управление и обслуживание в большой корпоративной среде.

Для решения основных вопросов модульности и оркестрации архитекторы переходят на систему триггеров на основе метаданных. Это значительный архитектурный скачок, который отделяет саму логику автоматизации от конфигурации того, как и когда она выполняется.

Эта инфраструктура основана на трех ключевых преимуществах:

  • Разделение: Вместо одного класса средства обработки базовая бизнес-логика разделена на небольшие атомарные классы Apex (например, класс RecalculateAccountValues или класс NotifySalesLeads), где каждый класс придерживается принципа единой ответственности. Эта модульность упрощает проверку, отладку и понимание логики изолированно.

  • Заказ и хореография: Заказ-наряд больше не программируется жестко в Apex. Вместо этого он декларативно определяется записями конфигурации, обычно хранимыми в типе настраиваемых метаданных (например, TriggerAction__mdt). Это позволяет администраторам повторно заказывать, добавлять или удалять действия автоматизации, просто изменив запись метаданных, которая не требует развертывания или изменения кода.

  • Функции обхода: Инфраструктура предоставляет стандартизированные детализированные функции обхода. Каждое действие автоматизации может быть настроено посредством записи метаданных на глобальное выключение или пропущено для определенных административных пользователей посредством ссылки на настраиваемое полномочие.

Один триггер Apex для объекта потом служит только динамическим диспетчером. Он не содержит бизнес-логики, а обрабатывает центральный класс MetadataTriggerHandler. Это средство обработки запрашивает записи настраиваемых метаданных для динамического определения последовательности выполнения и вызова правильных атомных классов Apex в установленном порядке. Автоматизация объединена в единый, прозрачный и управляемый слой.

Важным преимуществом использования Apex в надежной инфраструктуре является возможность управлять состоянием транзакций и оптимизировать производительность, исключив лишнюю работу. По мере накопления логики, разные автоматизации в заказе на сохранение обычно независимо выполняют одни и те же дорогостоящие операции, расходуя ценные контролирующие ограничения и увеличивая время работы DML.

Эта инфраструктура создана для решения этой проблемы с помощью двух основных стратегий:

  • Управление общими областями: В рамках одной транзакции Apex статические свойства и переменные используются для кэширования данных. Это обеспечивает выполнение дорогостоящей операции, например, запроса SOQL для параметра конфигурации, только один раз, даже если логика автоматизации вызывается несколько раз в разных записях или этапах триггера. Потребление транзакционных ограничений значительно снижается.

  • Использование кэша платформы: Чтобы выйти за рамки простого кэширования внутри транзакций, используйте кэш платформы, чтобы избежать запроса определенных данных ко всей базе данных. Этот управляемый кэш памяти идеально подходит для извлечения данных, которые не являются простыми, часто читаются в базе кода и неизменны в процессе транзакции (например, профили, роли, часы работы). С помощью Cache.CacheBuilder интерфейса система сперва проверяет кэш и выполняет запрос к базе данных только при отсутствии данных, повышая производительность и масштабируемость.

Всегда используйте обновление перед сохранением, если автоматизации нужно изменить только значения полей в записи, которая запускает транзакцию. Это относится как к обновлениям быстрого поля в потоке (которые выполняются до сохранения), так и к логике до контекста в триггерах Apex (до вставки, до обновления).

Данная схема является производительной, независимо от используемого инструмента, поскольку она позволяет избежать повторной операции DML и рекурсивного цикла сохранения. Изменения вносятся в запись в памяти до ее подтверждения в базе данных и сохраняются как часть исходной транзакции. Накладные расходы на второе сохранение, которые в противном случае повторно выполняли бы весь заказ на сохранение и снова запускали всю автоматизацию, устраняются.

Неуправляемая рекурсия — это типичная ошибка в триггерах последующего обновления, когда логика триггера выполняет обновление DML, что, в свою очередь, приводит к повторному запуску того же триггера. Таким образом создается бесконечный цикл, который в конечном итоге завершается исключением управляющего ограничения. Хотя статические логические флаги или коллекции обработанных кодов записей исторически использовались для предотвращения такой рекурсии, более точной и надежной схемой является заполнение логики путем сравнения значений полей между новой и старой версиями самой записи.

Выполняйте логику, только если определенное поле интереса действительно изменилось. Это предотвращает выполнение триггером логики последующих операций DML в одной транзакции, где критические данные остаются неизменными.

В потоке, запущенном записью, предотвратите неконтролируемую рекурсию, установив выполнение потока только при обновлении записи в соответствии с требованиями к условиям:

Управление рекурсией в потоке, запущенном записью

Если вы хотите использовать формулу критериев входа в потоке, вы можете предотвратить беглую рекурсию, сравнив глобальную переменную $Record (представляющую новые значения) с глобальной переменной $RecordPrior (представляющей исходные значения до сохранения). Например, чтобы обеспечить выполнение потока только при изменении поля «Стоимость» в возможности, используйте это в критериях записи:

Сравните значения полей из новой версии записи, Trigger.new, со значениями полей из старой версии записи, Trigger.oldMap, чтобы узнать, произошло ли конкретное изменение. Этот метод обеспечивает императивность автоматизации и ее запуск только при необходимости, повышая эффективность системы и предотвращая катастрофические рекурсивные циклы.

Хорошо созданная организация Salesforce требует последовательного и надежного механизма для обхода автоматизации. Это не дополнительная функция, а основное оперативное требование для сохранения целостности данных и включения административных задач.

Инфраструктура обхода важна для некоторых сценариев:

  • При загрузке больших объемов данных триггеры запуска для каждой записи могут резко замедлить процесс, привести к ограничению исключений и создать ошибочные связанные записи и уведомления. Обход позволяет вставлять данные чисто и эффективно.

  • Пользователю интеграции может понадобиться синхронизация данных из внешней системы записи. Автоматизация, которая обычно запускает инициированное пользователем изменение (например, отправка сообщения эл. почты, создание задачи), может быть нежелательной или избыточной, если изменение исходит из другой системы.

  • Администраторам или обслуживающему персоналу может понадобиться выполнить корректирующие обновления записей. Механизм обхода позволяет им вносить эти изменения без запуска стандартной автоматизации бизнеса, что может привести к непредвиденным последствиям.

Настраиваемые полномочия: Современным масштабируемым стандартом внедрения логики обхода являются настраиваемые полномочия. Они превосходят старые методы по нескольким причинам:

  • Гибкость: Настраиваемые полномочия могут быть назначены пользователям посредством наборов полномочий. Эта практика соответствует современной модели безопасности и доступа Salesforce, что позволяет детализировать и гибко назначать. Шунтирование может быть предоставлено определенному пользователю или даже временно с определенной датой/временем истечения срока действия.

  • Обслуживаемость: Использование настраиваемых полномочий позволяет избежать жесткого кодирования профилей или пользователей в логике автоматизации. Если роль пользователя меняется или новому профилю нужен обходной доступ, изменение является простым назначением набора полномочий, а не изменением кода или потока, требующим развертывания.

  • Масштабируемость: Настраиваемые полномочия предоставляют масштабируемую инфраструктуру для управления исключениями в сложной базе пользователей. Они могут быть назначены пользователям посредством набора полномочий, групп наборов полномочий или профилей. Их связывание с набором полномочий или профилем также доступно в исходных метаданных.

Схемы осуществления: Примените последовательную схему обхода ко всей автоматизации, запущенной записью в организации.

Пропуск потока, запущенного записью: Самый эффективный способ обойти поток - предотвратить его выполнение. Это достигается добавлением условия к критериям входа потока.

  • В элементе запуска потока, запущенного записью, установите требования к условиям на значение «Формула оценивается как истинная».

    • В конструкторе формул добавьте проверку настраиваемого полномочия посредством глобальной переменной $Permission. Сочетайте проверку с существующими критериями входа.

      • Схема формулы:
    • Данная схема обеспечивает выполнение потока только при отсутствии назначенного настраиваемого полномочия. Эта проверка выполняется еще до создания сеанса потока, что делает его наиболее эффективным методом.

Пропуск инфраструктуры триггеров Apex: В Apex интегрируйте логику обхода напрямую в инфраструктуре триггеров под управлением метаданных, что позволит детализировать управление.

  • Тип настраиваемых метаданных TriggerAction__mdt должен содержать текстовое поле, например, BypassPermission__c.

    • В классе MetadataTriggerHandler перед динамическим выполнением действия код должен прочитать значение из этого поля.

    • Если поле заполнено, средство обработки использует метод FeatureManagement.checkPermission() для определения наличия указанных настраиваемых полномочий у текущего текущего пользователя.

    • Если checkPermission() возвращает значение true, то обработчик пропускает это определенное действие и переходит к следующему в последовательности.

    • Эта схема эффективна, поскольку она позволяет одновременно и глобальный обход (если все записи TriggerAction__mdt ссылаются на одно и то же полномочие), и детализированный обход каждого действия (если разные записи ссылаются на разные полномочия или некоторые вообще не имеют полномочий обхода).

Это антипаттерн консолидации всей автоматизации объекта в единый массивный мегапоток. Консолидация в одном потоке по сравнению с разделением логики на несколько хорошо кондиционированных потоков не оказывает серьезного влияния на производительность. Наиболее значительный прирост производительности достигается за счет:

  • Использование потоков перед сохранением для обновлений полей одинаковой записи.

  • Написание точных условий входа для обеспечения исключения потоков из выполнения изменений, не влияющих на их конкретный сценарий использования.

Проводник по триггерам потока позволяет назначить значение заказа каждому потоку объекта, гарантируя последовательный заказ выполнения.

Проводник по триггерам потока
Apex Поток Операции