CPU 제한을 방지하기 위한 대량 처리된 레코드 처리 예제
Apex_CPU_TIME_LIMIT_EXCEEDED 오류를 방지하는 대량 처리 패턴을 사용하도록 플로를 refactor하는 방법을 알아봅니다. 이 예는 비효율적인 플로 설계와 최적화된 플로 설계 간의 차이점을 보여줍니다.
필수 Edition
| 지원되는 Edition 보기. |
| 필요한 사용자 권한 | |
|---|---|
| Einstein 및 Agentforce for Flow를 포함하여 Flow Builder에서 사용할 수 있는 모든 플로 유형, 요소 및 기능을 사용하여 플로를 열고, 편집하고, 만들고, 활성화하거나 비활성화하려면 다음을 수행합니다. | 플로 관리 |
이 예는 루프 내에서 데이터 조작 언어(DML)를 수행하는 플로를 효율적으로 레코드를 처리하는 대량 처리된 플로로 변환하는 방법을 보여줍니다. 전후 비교를 보고 플로 대량 처리 원칙을 살펴봅니다.
시나리오
기회가 마감되면 실행되는 레코드 트리거형 플로를 구축합니다. 마감-수주한 각 기회의 경우 플로가 기회 팀의 각 구성원에 대한 팔로우업 과업을 만듭니다. 플로:
- 모든 기회 팀 구성원을 가져옵니다.
- 각 팀 구성원에게 할당된 과업을 만듭니다.
- 사용자가 한 번에 여러 기회를 업데이트하는 경우에도 효율적으로 작동합니다.
- 대량 작업 중에 Apex_CPU_TIME_LIMIT_EXCEEDED 오류를 방지합니다.
Salesforce는 동기화 트랜잭션당 10,000밀리초(10초)의 단일 CPU 시간 제한을 적용합니다. 해당 트랜잭션의 모든 자동화(Apex 트리거, 플로, 워크플로 규칙 및 프로세스)는 동일한 예산에서 가져옵니다. 비효율적인 플로 설계로 인해 문제가 복잡해집니다. 트랜잭션의 기타 자동화는 공유 예산을 먼저 축소하고 비효율적인 플로를 사용하면 필요한 것보다 많은 남은 예산이 소비됩니다.
플로가 실행되는 순서는 플로 유형에 따라 다릅니다. 이 예에서는 저장 전 플로보다 나중에 실행되는 저장 후 레코드 트리거형 플로를 사용합니다. 실행 순서에 대한 자세한 내용은 트리거 및 실행 순서를 참조하십시오.
비효율적인 접근 방식: 루프 내 DML 작업
이 접근 방식을 사용하면 여러 기회를 처리할 때 CPU 제한 오류가 발생합니다.
유량 구조: 플로는 단계가 "수주 마감"인 경우 레코드 업데이트 후 실행되는 기회 개체의 레코드 트리거 플로로 시작됩니다. 플로는 레코드 가져오기를 사용하여 트리거 레코드에 대한 기회 팀 구성원을 가져온 다음, 컬렉션을 루프합니다. 루프 내에서 레코드 만들기 요소는 각 팀 구성원에 대해 하나의 과업을 만듭니다.
이 접근 방식이 실패하는 이유:
- 각 루프 반복은 별도의 DML 작업을 수행합니다.
- 팀 구성원이 5명인 기회는 5개의 DML 작업을 수행합니다.
- 사용자가 한 번에 20개의 기회를 업데이트하면 플로가 하나의 트랜잭션에서 모든 기회를 처리합니다.
- 20개의 기회 × 각각 5명의 팀 구성원 = 하나의 트랜잭션에서 100개의 DML 작업.
- 100개의 DML 작업에서 누적된 CPU 시간이 총괄자 제한을 초과합니다.
- 결과: APEX_CPU_TIME_LIMIT_EXCEEDED 오류.
효율적인 접근 방식: 컬렉션 기반 대량 처리
이 접근 방식은 볼륨에 상관없이 효율적으로 레코드를 처리합니다.
유량 구조: 플로는 기회 개체의 레코드 트리거 플로로 시작하고 레코드 가져오기를 사용하여 기회 팀 구성원을 가져옵니다. 플로에서 과업 레코드 변수 및 과업 레코드 컬렉션 변수를 만듭니다. 레코드 변수는 플로가 작업 중인 현재 과업을 포함하며, 레코드 컬렉션은 생성할 과업을 포함합니다. 플로는 팀 구성원을 통해 루프됩니다. 루프 내에서 할당 요소는 과업 레코드 변수에 대한 값을 설정하여 각 과업 레코드를 구축하고 과업을 루프의 현재 팀 구성원에 연결합니다. 다른 할당 요소는 과업 레코드 값을 과업 레코드 컬렉션에 추가합니다. 루프가 완료되면 단일 레코드 만들기 요소가 컬렉션의 모든 과업을 만듭니다.
이 작업 이유:
- 루프는 DML 작업을 수행하지 않고 과업 레코드 컬렉션을 작성합니다.
- 루프가 완료되면 하나의 DML 작업만 수행됩니다.
- 팀 구성원이 5명인 기회는 한 번에 5개의 과업을 만드는 DML 작업만 수행합니다.
- 사용자가 한 번에 20개의 기회를 업데이트하면 플로에서 총 20개의 DML 작업(기회당 1개)을 수행합니다.
- CPU 시간 소비량이 크게 줄어듭니다.
- 결과: 총괄자 제한에 도달하지 않고 플로가 성공적으로 완료됩니다.
성능 비교
| 시나리오 | 비효율적(루프의 DML) | 효율적(불충제됨) |
|---|---|---|
| 팀 구성원이 5명인 기회 1개 | DML 작업 5개 | 1 DML 작업 |
| 팀 구성원이 각각 5명인 기회 20개(대량 업데이트) | 100개의 DML 작업 (CPU 제한 오류와 함께 실패할 가능성) |
20개의 DML 작업 (완료 성공) |
| 팀 구성원이 각각 3개인 100개의 기회(데이터 로드) | 300개의 DML 작업 (정확히 실패) |
100개의 DML 작업 (완료 성공) |
대량 처리의 핵심 원칙
- 루프 내부에서 DML 작업을 수행하지 마십시오. 루프 도중 항상 컬렉션 변수에서 레코드를 수집한 후 루프가 완료된 후 DML을 수행합니다.
- 초기부터 대량 작업을 위한 설계. 레코드 트리거 플로가 여러 레코드를 동시에 처리한다고 가정합니다.
- 레코드 컬렉션 변수를 사용합니다. 컬렉션 기반 DML 작업은 개별 작업보다 크게 효율적입니다.
- 실제 볼륨으로 테스트합니다. 단일 레코드가 있는 디버그 모드는 대량 작업 문제를 표시하지 않습니다. 데이터 가져오기 마법사, Data Loader 또는 대량 업데이트를 사용하여 테스트합니다.
- 성능 모니터링. 프로덕션에서 실패하기 전에 디버그 로그를 검토하여 총괄자 제한에 근접하는 플로를 식별합니다.
상위 수준 단계
이 예제의 단계를 검토합니다. 순서에 따라 작업을 수행하거나 섹션으로 이동하여 자세한 지침을 확인하십시오.
- 플로 만들기
기회가 마감되면 실행되도록 레코드 트리거형 플로를 설정합니다. - 자원 만들기
대량 처리에 필요한 변수를 만듭니다. - 팀 구성원 가져오기
레코드 가져오기 요소를 사용하여 처리할 기회 팀 구성원 레코드를 가져옵니다. - 팀 구성원 확인을 위한 결정 추가
팀 구성원이 없는 경우 처리되지 않도록 결정 요소를 추가합니다. - 루프 요소 추가
루프 요소를 추가하여 팀 구성원을 통해 반복합니다. - 루프 내에서 과업 레코드 구축
루프 내의 각 팀 구성원에 대한 TaskRecord 레코드 변수의 필드 값을 채웁니다. - 컬렉션에 과업 추가
대량 생성을 위해 각 과업 레코드를 TasksToCreate 컬렉션 변수에 추가합니다. - 루프 후 모든 과업 만들기
단일 레코드 만들기 요소를 사용하여 단일 작업에서 모든 과업을 만듭니다. - 오류 처리 추가
오류를 수집하고 보고할 수 있도록 오류 관리를 구성합니다. - 대량 데이터로 테스트
대량 처리된 플로를 테스트하려면 대량 작업을 시뮬레이션해야 합니다. - 추가 최적화 기법
다음 기술을 사용하여 대량 처리된 플로를 추가로 최적화합니다. - 기존 플로 변환
루프에서 데이터 조작 언어(DML) 작업을 사용하여 플로를 대량 처리된 패턴으로 변환합니다.
플로 만들기
기회가 마감되면 실행되도록 레코드 트리거형 플로를 설정합니다.
-
플로 목록 보기를 엽니다.
- Setup(설정)에서 Quick Find(빠른 검색) 상자에 Flow(플로)를 입력한 다음 Flow(플로)를 선택합니다.
- Automation 앱에서 Flows 탭을 선택합니다.
- Lightning 앱의 플로 탭에서 작업 메뉴를 클릭하고 플로 열기를 선택합니다.
-
레코드 트리거형 플로를 만듭니다.
- Automation Lightning 앱에서 New(새로 만들기)를 클릭합니다. 검색하여 레코드 트리거형 플로를 선택합니다.
- 설정에서 새 플로를 클릭하고 검색하여 레코드 트리거형 플로를 선택합니다.
시작 구성 패널이 열립니다. -
시작 요소를 구성합니다.
- 개체로 기회를 선택합니다.
- 플로 트리거 시점에서 레코드가 업데이트됨을 선택합니다.
- 항목 조건 설정 섹션의 조건 요구 사항에 대해 모든 조건 충족(AND)을 선택합니다.
- 필드로 상태를 선택합니다.
- 연산자에 같음을 선택합니다.
- 값으로 마감 수주를 선택합니다.
- 플로 최적화에서 작업 및 관련 레코드를 선택합니다.
자원 만들기
대량 처리에 필요한 변수를 만듭니다.
-
각 과업을 구축하려면 과업 레코드를 구축할 레코드 변수를 만듭니다.
-
도구 상자를 열려면
를 클릭합니다.
- 새 자원을 클릭한 다음, 변수를 선택합니다.
- API 이름에 TaskRecord를 입력합니다.
- 데이터 유형으로 레코드를 선택합니다.
- 개체로 과업을 선택합니다.
- 완료를 클릭합니다.
-
도구 상자를 열려면
-
모든 과업을 저장하려면 모든 과업에 대한 레코드 모음 변수를 만듭니다.
- 새 자원을 클릭한 다음, 변수를 선택합니다.
- API 이름에 TasksToCreate를 입력합니다.
- 데이터 유형으로 레코드를 선택합니다.
- 개체로 과업을 선택합니다.
- 다중 값 허용(컬렉션)을 선택합니다.
- 완료를 클릭합니다.
팀 구성원 가져오기
레코드 가져오기 요소를 사용하여 처리할 기회 팀 구성원 레코드를 가져옵니다.
-
를 클릭한 다음, 검색 및 레코드 가져오기를 선택합니다.
-
요소를 구성합니다.
- 레이블에 기회 팀 구성원 가져오기를 입력합니다.
-
개체로 기회 연락처 역할을 선택합니다.
이 예에서는 플로가 기회 연락처 역할 개체에 팀 구성원을 저장합니다. 연락처에 기회를 연결하는 개체입니다.
- 기회 연락처 역할 레코드 필터링 섹션의 필드로 기회 ID를 선택합니다.
- 연산자에 같음을 선택합니다.
- 값으로 기회 트리거 및 기회 ID를 차례로 선택합니다.
- 저장할 레코드 수에 대해 모든 레코드를 선택합니다.
- 레코드 데이터 저장 방법에서 모든 필드 자동 저장을 선택합니다.
팀 구성원 확인을 위한 결정 추가
팀 구성원이 없는 경우 처리되지 않도록 결정 요소를 추가합니다.
-
를 클릭한 다음, 검색을 클릭하고 결정을 선택합니다.
-
결정을 구성합니다.
- 레이블에 찾은 팀 구성원?를 입력합니다.
- API 이름이 자동으로 채워집니다.
- 결과 레이블에 예를 입력합니다.
- API 이름이 자동으로 채워집니다.
- 자원에 대해 기회 팀 구성원 가져오기에서 기회 연락처 역할을 선택합니다.
- Operator(연산자)로 Is Null(Null임)을 선택합니다.
- Value(값)로 False를 선택합니다.
- 기본 결과를 클릭합니다.
- 레이블에 No를 입력합니다.
루프 요소 추가
루프 요소를 추가하여 팀 구성원을 통해 반복합니다.
-
예 경로에서
를 클릭한 다음, 검색 및 루프를 선택합니다.
-
루프를 구성합니다.
- 레이블에 Team Members를 통해 반복을 입력합니다.
- API 이름이 자동으로 채워집니다.
-
모음 변수의 경우 기회 팀 구성원 가져오기에서 기회 연락처 역할을 선택합니다.
이 리소스는 여러 레코드가 포함되어 있는 경우에도 단수로 표시됩니다.
- 방향으로 첫 번째 항목에서 마지막 항목을 선택합니다.
루프 내에서 과업 레코드 구축
루프 내의 각 팀 구성원에 대한 TaskRecord 레코드 변수의 필드 값을 채웁니다.
-
For Each에서
을 클릭한 다음, 할당을 검색하고 선택합니다.
-
할당을 구성합니다.
- 레이블에 과업 레코드 구축을 입력합니다.
- API 이름이 자동으로 채워집니다.
- 변수에 대해 TaskRecord를 선택한 다음, 주체를 선택합니다.
- 연산자에 같음을 선택합니다.
- 값에 마감된 기회에 대한 팔로우업을 입력합니다.
- + 할당 추가를 클릭합니다.
-
계속해서 할당을 추가하고 값을 설정합니다.
자원 연산자 값 TaskRecord>상태 같음 시작되지 않음 TaskRecord>우선 순위 같음 높음 TaskRecord>할당 대상 ID 같음 루프>연락처 ID의 현재 항목 TaskRecord>관련 ID 같음 트리거 기회>기회 ID
컬렉션에 과업 추가
대량 생성을 위해 각 과업 레코드를 TasksToCreate 컬렉션 변수에 추가합니다.
-
할당 요소 다음에 계속해서 루프에 있는
를 클릭한 다음, 할당을 검색하고 선택합니다.
-
할당을 구성합니다.
- 레이블에 모음에 과업 추가를 입력합니다.
- 변수로 TasksToCreate를 선택합니다.
- 연산자에 추가를 선택합니다.
- 값으로 TaskRecord 및 전체 자원을 차례로 선택합니다.
루프 후 모든 과업 만들기
단일 레코드 만들기 요소를 사용하여 단일 작업에서 모든 과업을 만듭니다.
-
루프가 종료되면
를 클릭한 다음, 레코드 만들기를 검색하고 선택합니다.
-
요소를 구성합니다.
- 레이블에 모든 작업 만들기를 입력합니다.
- 레코드 필드 값을 설정하는 방법에서 레코드 변수에서를 선택합니다.
- 만들 레코드 수에 대해 다중을 선택합니다.
- 레코드 컬렉션으로 TasksToCreate를 선택합니다.
- 플로를 저장합니다.
- 레이블에 기회 팀 구성원에 대한 작업 만들기를 입력합니다.
- API 이름이 자동으로 채워집니다.
오류 처리 추가
오류를 수집하고 보고할 수 있도록 오류 관리를 구성합니다.
-
오류를 관리하려면 레코드 만들기 요소에 오류 경로를 추가합니다.
- 모든 작업 만들기 요소의 세 개의 점을 클릭하고 오류 경로 추가를 선택합니다.
-
오류 경로의 실패를 Salesforce 관리자에게 알리려면 이메일 보내기 작업을 추가합니다.
-
오류 경로에서
를 클릭한 다음, 검색 및 이메일 보내기를 선택합니다.
- 레이블에 관리자에게 오류 알림을 입력합니다.
- API 이름이 자동으로 채워집니다.
- 수신자 주소에 알림을 받으려는 사람의 이메일 주소를 입력합니다.
- 제목으로 주의가 필요한 흐름을 입력합니다.
- 본문에 기회 팀 구성원에 대한 과업 만들기 플로에 오류가 발생했습니다를 입력합니다. 다음은 오류입니다. 를 참조하세요.
- 자원 삽입을 클릭합니다.
- 실행 중인 플로를 선택한 다음, 오류 메시지를 선택합니다.
-
오류 경로에서
- 작업을 저장합니다.
대량 데이터로 테스트
대량 처리된 플로를 테스트하려면 대량 작업을 시뮬레이션해야 합니다.
- 개별 레코드를 테스트하려면 디버그 모드를 사용하여 하나의 기회를 업데이트하고 플로에서 과업을 올바르게 생성하는지 확인합니다.
- 플로를 활성화합니다.
-
Sandbox에서 대량 작업을 테스트하려면 데이터 가져오기 마법사, Data Loader 또는 목록 보기를 사용하여 한 번에 여러 기회를 업데이트합니다.
- 테스트 기회를 10~20개까지 만듭니다.
- 각 기회에 팀 구성원을 추가합니다.
- Data Loader 또는 대량 업데이트를 사용하여 모든 기회에서 동시에 단계를 "마감 수주"로 변경합니다.
- 플로가 오류 없이 모든 과업을 만드는지 확인합니다.
- 성능을 확인하려면 Apex 디버그 로그를 검토하여 CPU 시간 소비량이 허용 가능한 한도 내에 있는지 확인합니다.
추가 최적화 기법
다음 기술을 사용하여 대량 처리된 플로를 추가로 최적화합니다.
항목 조건을 사용하여 실행 제한
필요한 경우에만 실행되도록 플로 시작 요소에 조건을 추가합니다. 예를 들어 특정 금액 또는 특정 레코드 유형의 기회만 처리합니다.
중요하지 않은 작업에 대한 저장 후 고려
저장 후 레코드 트리거 플로는 기회를 저장한 후 팔로우업 과업을 만들 수 있습니다. 비동기식으로 실행되며 총괄자 제한이 더 높습니다.
대용량 배치 프로세스
기회에 정기적으로 수십 명의 팀 구성원이 있는 경우 실시간이 아닌 배치로 마감된 기회를 처리하는 예약된 플로를 사용합니다.
기존 플로 변환
루프에서 데이터 조작 언어(DML) 작업을 사용하여 플로를 대량 처리된 패턴으로 변환합니다.
루프에 DML 연산이 있는 기존 플로가 있는 경우 다음 단계를 수행하여 변환합니다.
- 루프에서 DML 작업을 찾으려면 루프 내의 모든 레코드 만들기, 레코드 업데이트, 레코드 삭제 요소를 식별합니다.
-
각 DML 요소에 대해 변환을 수행합니다.
- 레코드를 작성하려면 해당 개체 유형에 대한 레코드 변수를 만듭니다.
- 처리할 레코드를 저장하려면 해당 개체 유형에 대한 레코드 컬렉션 변수를 만듭니다.
- 레코드에 대한 필드 값을 저장하려면 할당 요소를 사용하여 레코드 변수에 값을 할당합니다.
- 처리할 레코드를 수집하려면 할당을 사용하여 레코드 모음에 레코드 변수를 추가합니다.
- 레코드를 효율적으로 만들려면 루프 다음에 전체 레코드 컬렉션을 처리하는 DML 요소를 하나 추가합니다.
- 변환을 확인하려면 대량 데이터를 사용하여 철저하게 테스트하여 리팩터링이 올바르게 작동하는지 확인합니다.

