본문 바로가기
SFDC 개념

APEX - Trigger

by 경 훈 2023. 6. 26.

Apex Trigger란?

세일즈포스가 제공하는, 레코드 관리 위한 자동화 툴.

  • 레코드 관리 서포트
  • 프로세스 중심 로직 구축
  • 더 강력함

 

 

 

Apex Trigger를 사용하면

  • insert, update, delete와 같은 세일즈포스 레코드에 대한 이벤트 전후에 custom action 수행 O
  • 특정 조건에 따라 작업을 수행, 관련 레코드 수정, 특정 작업이 발생하지 않도록 제한 O
  • SOQL, DML 실행, custom Apex 메소드 호출을 포함해 Apex에서 할 수 있는 모든 작업  O
  • 세일즈포스 유저 인터페이스에서 Point-and-Click 도구를 사용해 수행할 수 없는 작업 O
  • Account/Contact와 같은 top-level standard object, custom object, 일부 standard child object에 대해 Trigger 정의 O

 

 

 

Trigger Events

Before Trigger After Trigger
before insert after insert
before update after update
before delete after delete
  after undelete
(Recycle Bin에 있던거 undelete 할 때)

Before Trigger

: 아직 데이터베이스에 들어가지 않은 상태. Id도 안 만들어짐

=> Record의 value 바꿀 수 O

DB에 저장되기 전 레코드 값을 update/validate 하는 데 사용됨

 

After Trigger

: 데이터베이스에 들어간 상태. Id 생성됨

=> Id 이용해야 할 때 사용

시스템에서 설정한 필드 값(ex. record Id / LastModifiedDate 필드..) 및 다른 레코드의 변경 사항에 영향 줌

insert, delete, update (insert는 After Trigger에서만!)

 

 

 

Trigger와 실행 순서

 

 

Syntax

trigger TriggerName on ObjectName (trigger_events) {
    //code block
}

 

 

 

Context Variable

Trigger를 발생시킨 레코드에 액세스하려면 Context variable 사용

  • Trigger.New : insert/update trigger에 insert된 모든 레코드 포함
  • Trigger.Old : update trigger에서 업데이트되기 전의 sObject old version 또는 delete trigger에서 삭제된 sObject 목록 제공

하나의 레코드가 insert되거나 API/Apex를 통해 많은 레코드가 대량으로 insert될 때 트리거 발생 O

=> Trigger.New와 같은 컨텍스트 변수는 하나 또는 여러 레코드를 포함 O

각 개별 sObject를 가져오기 위해 Trigger.New 반복 O

 

시스템은 trigger 실행이 완료된 후 before trigger를 실행한 레코드 저장.
DML insert/update 작업을 명시적으로 호출하지 않고 trigger의 레코드 수정 가능.
해당 레코드에 대해 DML문을 수행하면 오류 발생

 

 

Variable Usage
isExecuting   Apex 코드의 현재 컨텍스트가 Visualforce page, Web service, executeanonymous( ) API call이 아닌
  trigger인 경우 true 반환
isInsert   User interface, Apex, API에서 insert 작업으로 trigger가 실행됐을 때 true 반환
isUpdate   User interface, Apex, API에서 update 작업으로 trigger가 실행됐을 때 true 반환
isDelete   User interface, Apex, API에서 delete 작업으로 trigger가 실행됐을 때 true 반환
isBefore   레코드가 저장되기 전에 trigger가 실행된 경우 true 반환
isAfter   모든 레코드가 저장된 후에 trigger가 실행된 경우 true 반환
isUndelete   Recycle Bin에서 레코드가 복구된 이후 trigger가 실행된 경우 true 반환
  이 복구는 세일즈포스 User interface, Apex, API에서 undelete 작업 후에 발생할 수 있음
new   sObject 레코드의 new 버전 리스트 반환
  이 sObject list는 insert, update, undelete trigger에서 사용 가능
  레코드는 before trigger에서만 수정 가능
newMap   sObject 레코드의 new 버전에 대한 ID Map
  이 Map은 before update, after insert, after update, after undelete trigger 에서만 사용 가능
old   sObject 레코드의 old 버전 리스트 반환
  이 sObject list는 update, delete trigger에서 사용 가능
oldMap   sObject 레코드의 old 버전에 대한 ID Map
  이 Map은 updatedelete trigger에서 사용 가능
operationType   현재 operation에 해당하는 System.TriggerOperation 형식의 enum 반환
  System.TriggerOperation enum에 가능한 value =>
  BEFORE_INSERT, BEFORE_UPDATEBEFORE_DELETE, AFTER_INSERTAFTER_UPDATE
  AFTER_DELETEAFTER_UNDELETE
  다른 트리거 type에 따라 프로그래밍 로직을 변경하는 경우 switch문을 사용하는 것이 좋음
size   old, new 트리거 호출의 총 레코드 수

 

operationType switch문 예시

 trigger AccountTrigger on Account (before delete, before insert, before update, 
                                    after delete, after insert, after update) {

    switch on Trigger.operationType {
        when AFTER_INSERT{
            //do after insert stuff
        }
        when AFTER_UPDATE{
            //Do after update stuff
        } 

    }
}

 

 

 

Trigger에서 Class Method 호출

Trigger에서 public utility method 호출 O

 

다른 클래스의 method를 호출하면 :

  • 코드 재사용 O
  • Trigger size 줄어듦
  • Apex 코드의 유지 관리 향상됨
  • 객체 지향 프로그래밍 사용 O

 

 

 

Trigger Exception

특정 데이터베이스 작업에 대해 제한을 추가해야 하는 경우

addError( ) : 트리거에 레코드 저장 방지

  • 트리거 내부에 치명적인 오류 발생시킴
  • 오류 메세지는 UI에 표시되고 기록됨
트리거에서 addError( ) 호출은 bulk DML이 partial success로 호출된 경우를 제외하고 전체 작업 세트가 roll back 되도록 함

- Apex의 DML문이 트리거를 생성한 경우 모든 오류가 전체 작업을 roll back.
  그러나 런타임 엔진은 여전히 작업의 모든 레코드를 처리하여 포괄적인 오류 목록 컴파일
- Lightning Platform API의 bulk DML 호출이 트리거를 생성한 경우 런타임 엔진이 잘못된 레코드를 따로 설정.
  그 후 런타임 엔진은 오류를 생성하지 않은 레코드의 부분 저장 시도

 

 

 

Trigger와 Callout

Apex를 사용하면 외부 Web service를 호출하고 Apex 코드를 외부 Web service와 통합 O

외부 Web service에 대한 Apex 호출 => Call out

트리거에서 Call out을 만들 때 외부 서비스의 응답을 기다리는 동안 트리거 프로세스가 작업을 차단하지 않도록 Call out을 비동기적으로 수행해야 함.

비동기 callout은 백그라운드 프로세스에서 이뤄지며 응답은 외부 서비스가 반환

 

트리거에서 Callout 만들기

@future(callout=true)

 

 

 

Trigger 작성 시 주의사항

SOQL Looping

trigger AccountTrigger on Account (before update) {
    if(Trigger.isUpdate) {
    	for(Account a : Trigger.New) {
            Opportunity[] opps = [SELECT Id, Name, Amount
            					  FROM Opportunity WHERE AccountId : a.Id];
        }
    }
}

for문 안에 SOQL문 들어가는 것 주의하기!

Account 레코드가 100개 이하면 문제없지만, 100개 넘어가면 Exception 발생

 

 

 

 

 

 

 


Bulk Apex Trigger

 

 

 

Apex Trigger는 대량으로 작동하도록 최적화 되어있음
트리거의 레코드를 처리하기 위해 bulk design pattern 사용

 

 

 

Bulk design pattern 사용의 이점 :

  • 트리거 성능 향상
  • 서버 리소스 덜 소모됨
  • Platform Limit 초과할 가능성 줄어듦

 

코드 대량화 이점 :

  • 많은 수의 레코드 효율적으로 처리 O
  • Lightning Platform governor limit* 내에서 실행 O

*Governor limit : runaway code가 multitenant platform의 리소스를 독점하지 않도록 하기 위한 것

 

 

 

Bulk SOQL

  • 하나의 쿼리에서 related record 검색, 여러 조건의 조합 확인 O
  • 더 적은 코드 작성
  • DB에 대한 쿼리 더 적게 작성 O  (=> Synchronous Apex의 경우 100개의 SOQL 쿼리, Asynchronous Apex의 경우 200개의 쿼리 limit에 도달하는 것 방지하는 데 도움)
트리거는 한 번에 200개의 레코드 batch에서 실행됨
( 400개의 레코드로 인해 트리거 실행 => 200*2번 실행 )

 

 

 

Bulk DML

트리거/클래스에서 DML call을 수행할 때 가능한 경우 sObject collection에 대해 DML call 수행

각 sObject에서 개별적으로 수행하면 리소스 비효율적으로 사용됨

Apex 런타임은 하나의 트랜잭션*에서 최대 150개 DML call 허용

 

*Apex transaction : 여러 개의 작업들이 단일 유닛 형태로 실행되는 것

 

 

 

 

Transaction당 Apex Limits

  Synchronous Apex Asynchronous Apex
  실행된 총 SOQL 쿼리 수 100 200
  SOQL 쿼리로 검색된 총 레코드 수 50,000  
  Database.getQueryLocator로 검색된 총 레코드 수 10,000  
  실행된 총 DML문 수 150
(1번의 트랜잭션 당 150번)
 
  DML문 / Approval.process / database.emptyRecycleBin의 결과로 처리된
  총 레코드 수
10,000  
  insert, update, delete문으로 트리거를 반복적으로 발생시키는 Apex 호출의
  총 스택 depth
16  
  한 트랜잭션에서 총 callout(HTTP request / web service callout)의 수 100  
  총 heap 사이즈 6MB 12MB
  세일즈포스 서버의 최대 CPU 시간 10,000ms (10초) 60,000ms (60초)

출처 : Apex Developer Guide - Execution Governors and Limits

 

 

 

 

 

 

출처 : http://jaee-h.tistory.com/entry/Apex-basic-04Trigger

참조 : Trailhead - Apex Triggers

'SFDC 개념' 카테고리의 다른 글

Visualforce - 기본2  (0) 2023.06.26
Visualforce - 기본1  (0) 2023.06.26
APEX - Apex&.Net  (0) 2023.06.26
APEX - Class  (0) 2023.06.26
APEX - 기본  (0) 2023.06.26

댓글