안녕하세요 모델와이입니다.
SAP에서는 CALL FUNCTION ... STARTING NEW TASK 문법을 이용해 **여러 개의 작업(Task)**을 동시에 실행할 수 있습니다.
이는 Dialog Work Process를 여러 개 사용하는 방식으로, CPU 병렬 분산 처리와 유사한 개념입니다.
주로 사용하는 상황:
- 대량 전표 처리
- 인터페이스 수신 후 데이터 정제 및 Posting
- 보고서 집계 등 독립적인 작업들을 동시에 수행할 수 있을 때
ㄱ. 기본 로직 예시
1. 병렬 처리용 RFC Function Module 예시 (ZFI_PARALLEL_TASK)
FUNCTION ZFI_PARALLEL_TASK.
*" Remote-enabled Function
DATA: lv_count TYPE i.
LOOP AT it_data INTO wa_data.
" 데이터 처리 로직
lv_count = lv_count + 1.
ENDLOOP.
" 결과 저장 (예: DB INSERT)
ENDFUNCTION.
2. 메인 프로그램에서 병렬 호출
DATA: lt_split TYPE STANDARD TABLE OF zfi_data,
lv_taskname TYPE string,
lv_task_count TYPE i VALUE 0.
FIELD-SYMBOLS: <lt_sub> TYPE zfi_data_tab.
" 데이터를 구간으로 나눔 (예: 5건씩 분리)
CALL FUNCTION 'Z_SPLIT_DATA' " 직접 구현 필요
EXPORTING
it_full = lt_data
iv_chunk_size = 100
IMPORTING
et_splits = lt_split.
LOOP AT lt_split ASSIGNING <lt_sub>.
lv_taskname = |TASK_{ lv_task_count }|.
lv_task_count = lv_task_count + 1.
CALL FUNCTION 'ZFI_PARALLEL_TASK'
STARTING NEW TASK lv_taskname
DESTINATION IN GROUP DEFAULT
PERFORMING callback_form ON END OF TASK
TABLES
it_data = <lt_sub>.
ENDLOOP.
WAIT UNTIL lv_done_count = lv_task_count.
3. Callback FORM
FORM callback_form USING taskname.
lv_done_count = lv_done_count + 1.
WRITE: / taskname, '완료'.
ENDFORM.
ㄴ. 기본 로직 예시
1. JOB OPEN 로직을 통한 처리
DATA : lv_jobname TYPE tbtcjob-jobname,
lv_number TYPE tbtcjob-jobcount,
lv_job_released,
lv_condition TYPE string,
lt_save_log TYPE ztlog,
ls_save_log TYPE TABLE OF ztlog,
lv_count TYPE p.
CLEAR : lv_condition.
"lt_data는 본인이 데이터를 나눠놓은 분류대로 정의
LOOP AT lt_data INTO ls_data.
CLEAR : lv_jobname, lv_number.
"배치 이름 입력
lv_jobname = |BATCH_{ sy-datum+2 }{ sy-uzeit(4) }_{ ls_data-_data }|.
ADD 1 TO lv_count.
CALL FUNCTION 'JOB_OPEN'
EXPORTING
jobname = lv_jobname " Job Name
IMPORTING
jobcount = lv_number " ID Number of Background Job
EXCEPTIONS
cant_create_job = 1 " Job cannot be created, see system log
invalid_job_data = 2 " Job Contains Invalid Job Data, See SYSLOG
jobname_missing = 3 " Job Name Not Specified
OTHERS = 4.
IF sy-subrc EQ 0.
"배치실행 프로그램 메모리입력
EXPORT lv_jobname TO MEMORY ID 'BATCHJOB'.
"SUBMIT로직은 프로그램 별로 다르니 유의
SUBMIT zbatchprog VIA JOB lv_jobname NUMBER lv_number
WITH p_data = ls_data-data
WITH pv_jname = lv_jobname
AND RETURN.
ENDIF.
"log 기록을 위한 시간 입력
GET TIME.
"배치잡 종료
CALL FUNCTION 'JOB_CLOSE'
EXPORTING
jobcount = lv_number " Job number
jobname = lv_jobname " Job Name
sdlstrtdt = sy-datum
sdlstrttm = sy-uzeit
* direct_start = 'X'
IMPORTING
job_was_released = lv_job_released " = 'X', if Job Was Released
EXCEPTIONS
cant_start_immediate = 1 " Cannot Start Immediately
invalid_startdate = 2 " Start Condition is Invalid
jobname_missing = 3 " Job Name Missing (Wildcards Allowed)
job_close_failed = 4 " Error During JOB_CLOSE, See SYSLOG
job_nosteps = 5 " Job Specified Does Not Contain Any Steps
job_notex = 6 " Specified Job Does Not Exist
lock_failed = 7 " Lock Attempt Failed
invalid_target = 8 " Target Server or Group is Invalid
invalid_time_zone = 9 " Time Zone Invalid
OTHERS = 10.
"비정상 작동 시 배치잡 삭제
IF sy-subrc <> 0 OR lv_job_released = ''.
CALL FUNCTION 'BP_JOB_DELETE'
EXPORTING
jobcount = lv_number " ID number of the job
jobname = lv_jobname " Job Name
EXCEPTIONS
cant_delete_event_entry = 1 " Event Scheduling Cannot be Deleted
cant_delete_job = 2 " Job Cannot be Deleted
cant_delete_joblog = 3 " Job Log Cannot be Deleted
cant_delete_steps = 4 " Job Steps Cannot be Deleted
cant_delete_time_entry = 5 " Deadline Scheduling Cannot be Deleted
cant_derelease_successor = 6 " Previous Job Cannot be Modified
cant_enq_predecessor = 7 " Succeeding Job Cannot be Locked
cant_enq_successor = 8 " Previous Job Cannot be Locked
cant_enq_tbtco_entry = 9 " Job Cannot be Locked
cant_update_predecessor = 10 " Previous Job Cannot be Modified
cant_update_successor = 11 " Succeeding Job Cannot be Modified
commit_failed = 12 " COMMIT WORK Failed
jobcount_missing = 13 " Job ID number was not specified
jobname_missing = 14 " Job Name Not Specified
job_does_not_exist = 15 " Job Does Not Exist
job_is_already_running = 16 " Job Already Active
no_delete_authority = 17 " No Authorization to Delete Jobs
OTHERS = 18.
WRITE : / | { lv_count && '.' && ls_data-_data && ' ' && ls_data-txt } | && | 배치 생성 실패 |.
ELSE.
WRITE : / | { lv_count && '.' && ls_data-_data && ' ' && ls_data-txt } |.
ls_save_log-data = ls_data-data.
ls_save_log-jobname = lv_jobname.
ls_save_log = VALUE #( BASE ls_save_log ernam = sy-uname erdat = sy-datum erzet = sy-uzeit ).
APPEND ls_save_log TO lt_save_log.
CLEAR : ls_save_log.
ENDIF.
CLEAR : ls_data.
ENDLOOP.
"로그데이터 저장
IF lt_save_log[] IS NOT INITIAL.
MODIFY ztlog FROM TABLE lt_save_log.
ENDIF.
🧪 실전 팁
주의 사항 설명
작업 분할 기준 | 건 수 기준 또는 특정 키 기준으로 데이터 분리 |
RFC FM은 Stateless | 전역 변수 공유 불가. 전달값을 꼭 IMPORTING/TABLES에 명시해야 함 |
리소스 초과 방지 | SPBT_INITIALIZE로 병렬 Task 사용 가능 여부 사전 체크 필요 |
결과 통합 | 각 TASK에서 결과 DB 저장하거나 메모리로 모아서 후처리 가능 |
📌 마무리 정리
오늘은 배치잡 설정 시 병렬프로세스로 처리하는 내역에 대해서 살펴보았습니다.
궁금하신 사항이 있으시면 언제든 댓글로 문의주세요.
감사합니다~
'SAP ABAP' 카테고리의 다른 글
SAP ABAP 루프 제어 구문 정리 : ON CHANGE OF, AT NEW, AT END OF, AT FIRST, AT LAST (1) | 2025.05.28 |
---|---|
SAP ABAP 날짜 관련 Function Module (0) | 2025.05.27 |
SAP Background Job 관리와 SM37 분석 (0) | 2025.04.18 |
SAP 유효성 점검 및 대체 로직 기입 방법 (0) | 2025.03.24 |
SAP Structure 및 Table 필드 정보 변경 후 ALV 반영되지 않는 경우 (0) | 2025.02.26 |