View
Batch Apex 사용하기
Database.Batchable 인터페이스를 상속받아 Batch Apex 사용
Batch Apex를 모니터링/멈추려면 Setup → Apex Jobs
Database.Batchable 인터페이스 implement하기
Database.Batchable 인터페이스는 3개의 메소드가 필수로 포함되어야 함 :
1) start 메소드
2) execute 메소드
3) finish 메소드
1) start 메소드 :
public (Database.QueryLocator) | Iterable<sObject>) start(Database.BatchableContext bc) {}
인터페이스 메소드 execute에 전달할 레코드/객체를 수집하기 위해 batch Apex job의 시작 부분에서 start 메소드 호출.
Database.QueryLocator 오브젝트 또는 job에 전달된 레코드 또는 오브젝트를 담고있는 iterable을 반환.
단순 쿼리(SELECT)를 사용해 batch job에서 오브젝트의 scope를 생성하는 경우 Database.QueryLocator 오브젝트 사용.
QueryLocator 오브젝트를 사용하면 total number of records retrieved by SOQL queries에 대한 governor limit이 무시됨.
Batch job을 위한 복잡한 scope를 생성하려면 iterable을 사용.
list에서 반복하기 위한 custom process를 생성 가능.
interable을 사용하면 total number of records retrieved by SOQL queries에 대한 governor limit이 계속 적용됨.
더 자세한 내용 ☞ Batch Apex Best Practice
2) execute 메소드 :
public void execute(Database.BatchableContext BC, list<P>){}
각 데이터 청크에 대해 필요한 처리를 수행하려면 execute 메소드 사용.
이 메소드는 유저가 전달하는 각 레코드의 배치에 대해 호출됨.
execute 메소드에 필요한 것 :
- Database.BatchableContext 오브젝트 참조
- List<sObject>와 같은 sObject 리스트 또는 매개변수화된 유형의 리스트. Database.QueryLocator를 사용하는 경우, 반환된 list를 사용
레코드의 batch는 start 메소드에서 받은 순서대로 실행되는 경향이 있음
그러나 레코드의 batch가 실행되는 순서는 다양한 요인에 따라 달라지므로 실행 순서는 보장되지 않음.
3) finish 메소드 :
public void finish(Database.BatchableContext BC){}
확인 이메일을 보내거나 후처리 작업을 실행하려면 finish 메소드 사용
모든 batch가 실행된 후 이 메소드를 호출
Batch Apex job의 각 실행은 별개의 트랜잭션으로 간주됨.
예를 들어 1,000개의 레코드를 포함하고 Database.executeBatch의 선택적 scope 파라미터 없이 실행되는 Apex job은 200개의 레코드로 이루어진 5개의 트랜잭션으로 간주됨.
각 트랜잭션에 대해 Apex governor limit이 재설정됨.
첫번째 트랜잭션이 성공했지만 두번째 트랜잭션이 실패할 경우, 첫번째 트랜잭션에서 수행한 데이터베이스 업데이트는 롤백되지 X.
Database.BatchableContext 사용하기
Database.Batchable 인터페이스의 모든 메소드는 Database.BatchableContext 오브젝트 참조를 요구함
해당 오브젝트를 사용하여 Batch job의 진행률을 추적
Database.BatchableContext 오브젝트의 인스턴스 메소드
Name | Returns | Description |
getJobID | ID | 이 batch job과 연결된 AsyncApexJob 오브젝트의 ID를 String으로 반환. 이 메소드를 사용하여 batch job에서 레코드의 진행률 추적. System.abortJob 메소드에 이 ID를 사용할 수도 있음. |
batch job과 연관된 AsyncApexJob을 쿼리하기 위해 Database.BatchableContext를 사용하는 예시 :
public void finish(Database.BatchableContext BC){
//현재 job의 정보를 검색하기 위해 AsyncApexJob 쿼리하기
AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
TotalJobItems, CreatedBy.Email
FROM AsyncApexJob WHERE Id =
:BC.getJobId()];
//Apex job 제출인에게 job 완료를 알리는 이메일 보내기
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddress = new String[] {a.CreatedBy.Email};
mail.setToAddresses(toAddress);
mail.setSubject('Apex Sharing Recalculation ' + a.Status);
mail.setPlainTextBody
('The batch Apex job processed ' + a.TotalJobItems +
' batches with ' + a.NumberOfErrors + ' failures.');
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
Database.QueryLocator를 사용해 Scope 정의하기
메소드는 iterable 또는 batch job에서 사용하기 위한 레코드를 담고있는 Database.QueryLocator 오브젝트를 반환 O
Database.QueryLocator 사용 예시 :
public class SearchAndReplace implements Database.Batchable<sObject> {
public final String Query;
public final String Entity;
public final String Field;
public final String Value;
public SearchAndReplace(String q, String e, String f, String v) {
Query = q; Entity = e; Field = f; Value = v;
}
public Database.QueryLocator start(Database.BatchableContext BC) {
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext BC, List<sObject> scope) {
for(sobject s : scope) {
s.put(Field, Value);
}
update scope;
}
public void finish(Database.BatchableContext BC) {
}
}
Iterable을 사용해 Batch Apex에서 Scope를 정의하기
public class batchClass implements Database.batchable {
public Iterable start(Database.BatchableContext info) {
return new CustomAccountIterable();
}
public void execute(Database.BatchableContext info, List<Account> scope) {
List<Account> accsToUpdate = new List<Account>();
for(Account a : scope) {
a.Name = 'true';
a.NumberOfEmployees = 70;
accsToUpdate.add(a);
}
update accsToUpdate;
}
public void finish(Database.BatchableContext info) {
}
}
Database.executeBatch 메소드를 사용하여 Batch Job 제출하기
프로그래밍 방식으로 batch job을 시작하기 위해 Database.executeBatch 메소드를 사용
Database.executeBatch를 호출할 때, 세일즈포스는 대기열에 프로세스 추가.
서비스 가용성에 따라 실제 실행이 지연될 수 있음.
Database.executeBatch 메소드는 2개의 파라미터를 가짐 :
- Database.Batchable 인터페이스를 implement하는 클래스의 인스턴스
- 선택적 파라미터인 scope
- 이 파라미터는 execute 메소드에 전달할 레코드의 수를 지정
- 전달되는 각 레코드에 많은 작업이 있고, governor limit에 도달하는 경우 이 파라미터를 사용. 레코드 수를 제한하면 트랜잭션 당 작업을 제한 O.
- 이 값은 0보다 커야 함
- batch 클래스의 start 메소드가 QueryLocator를 반환하면, Database.executeBatch의 선택적 scope 파라미터는 최대 2,000개의 값을 가질 수 있음
- 더 높은 값으로 설정하면 세일즈포스는 QueryLocator에 의헤 반환된 레코드를 최대 2,000개의 레코드 batch로 더 작은 묶음으로 청크함.
- batch 클래스의 start 메소드가 iterable을 반환하면 scope 파라미터 값에는 상한이 없음.
- 하지만 높은 숫자를 사용하면 다른 limit을 만날 수 있음.
- 최적의 scope 사이즈 : 2000의 인수 (ex. 100, 200, 400)
Database.executeBatch 메소드는 진행률을 추적하는 job의 AsyncApexJob 오브젝트의 ID를 반환함 :
ID batchprocessid = Database.executeBatch(reassign);
AsyncApexJob aaj = [SELECT Id, Status, JobItemsProcessed, TotalJobItems, NumberOfErrors
FROM AsyncApexJob WHERE ID =: batchprocessid];
※ 출처 : Apex Developer Guide
'Apex' 카테고리의 다른 글
Apex Scheduler (0) | 2022.03.08 |
---|