SAP ABAP

SAP 배치 병렬 처리 (Parallel Processing)란?

모델와이 2025. 4. 23. 14:11

안녕하세요 모델와이입니다.

 

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 저장하거나 메모리로 모아서 후처리 가능

 


📌 마무리 정리

오늘은 배치잡 설정 시 병렬프로세스로 처리하는 내역에 대해서 살펴보았습니다.

궁금하신 사항이 있으시면 언제든 댓글로 문의주세요.

감사합니다~