Формирование фоновых заданий и массовый запуск транзакции ASKB/ASKBN

Изначальная постановка задачи сводилась к тому, что в системе необходим еженедельный автоматический запуск транзакции ASKB. Ничего сложного.

Загвоздка первая: транзакция ASKB полно и продуктивно работает только в фоновом режиме. На всякий пожарный случай от греха подальше.

Загвоздка вторая: транзакция ASKB не умеет работать с несколькими БЕ. Экран выбора не оставляет выбора. Если бы на нашем проекте было бы мало БЕ (одна-две-три), то можно было бы просто создать напрямую несколько фоновых заданий и дело в шляпе. Но если у нас сотня БЕ, то уже необходима собственная запускалка, раз стандартной нет никакой.

Отлично, приступаем к реализации.

 

Сначала необходимо собрать список БЕ. Есть варианты:

В моём случае достаточно первого варианта.

Затем надо определиться, каким образом обрабатывать список БЕ:

В моём случае БЕ много, операций мало, засорять журнал заданий пустыми вызовами не хочется. Я выбираю второй путь.

Если заглянуть внутрь транзакции ASKB, то можно посмотреть как она определяет надо ли запускаться:

 

  loop at gt_process assigning <fs_process>.

    select * from tabas into table lt_tabas
                       up to 1 rows
                       where bukrs = <fs_process>-bukrs
                       order by cpudt descending
                                cputm descending
                                blnrt descending.
    if sy-subrc = 0.
      read table lt_tabas index 1.
      <fs_process>-tabas_cpudt = lt_tabas-cpudt.
      <fs_process>-tabas_cputm = lt_tabas-cputm.
    endif.

    select single * from anek into ls_anek
     where bukrs = <fs_process>-bukrs
       and ( cpudt  > <fs_process>-tabas_cpudt  or
             cpudt  = <fs_process>-tabas_cpudt and 
             cputm  > <fs_process>-tabas_cputm ).

    if sy-subrc = 0.
      <fs_process>-anek_cpudt = ls_anek-cpudt.
      <fs_process>-anek_cputm = ls_anek-cputm.
      <fs_process>-action = 'I'.
    endif.

  endloop.

Вот мы и выяснили, какие БЕ надо обрабатывать. Значит можно приступить к следующему шагу: сформировать фоновое задание. Сначала смотрим, что за программа стоит за транзакцией ASKBN – это RAPERB2000. Самая обыкновенная программа типа REPORT, которую можно дёрнуть просто через SUBMIT REPORT.

Значит, нам требуется следующая последовательность действий по каждой БЕ:

  1. сформировать имя для фонового задания
  2. открыть фоновое задание
  3. сформулировать задание по данной БЕ
  4. закрыть фоновое задание

 

Приступим:

  
  loop at gt_process where action = 'I'.

    concatenate 'RAPERB2000' gt_process-bukrs 
      into lv_jobname separated by '_'.

    call function 'JOB_OPEN'
      exporting
        jobname          = lv_jobname
      importing
        jobcount         = lv_jobcount
      exceptions
        others           = 99.

    submit raperb2000
            with p_bukrs  = gt_process-bukrs
            with p_test   = p_test
            with p_einzel = 'X'
            with p_einzld = 'X'
            with p_normal = 'X'
            with p_rstart = ' '
      via job lv_jobname number lv_jobcount
      and return.

    call function 'JOB_CLOSE'
      exporting
        jobcount             = lv_jobcount
        jobname              = lv_jobname
        strtimmed            = 'X'
      exceptions
        others               = 99.

  endloop.

Всё просто. И что получается в итоге? Мы не задаём дополнительные параметры, это значит параметры печати будут по умолчанию, и что задание будет запущено немедленно. Меня это полностью устраивает.

А вот читатель мне возразит: “Но если сформировать 100 заданий в один момент времени, то будет очень неприятная пиковая нагрузка”.  Тут всё просто: сервер не запускает немедленно сразу все задания, а будет обрабатывать их небольшими порциями. Следовательно, проблемы перегрузки не возникнет.

Уже можно идти в планировщик, но не хватает контроля результатов. На практике ASKB может упасть с ошибкой. Следовательно, финальными штрихами станет отслеживание результатов запуска.

Для отслеживания ситуации есть два направления:

Второе направление мне видится предпочтительней и перспективней. Приступаем:

    do.
      wait up to 6 seconds.
      lv_count = lv_count + 1.


      call function 'SHOW_JOBSTATE'
        exporting
          jobcount = lv_jobcount
          jobname  = lv_jobname
        importing
          finished = lv_finished
        exceptions
          others   = 99.

      if lv_finished = 'X'.
        exit.
      elseif lv_count > 50.
        exit.
      endif.
    enddo.

    call function 'BP_JOBLOG_READ'
      exporting
        jobcount  = lv_jobcount
        jobname   = lv_jobname
      tables
        joblogtbl = lt_joblog[]
      exceptions
        others    = 99.

Последний ФМ нам вернул простую и понятную таблицу со списком возникших ошибок. Сам спул читать не обязательно – это очень радует.

Здесь уже возможны разные варианты:

 

Для большой красоты можно реализовать всё сразу. Но это уже потом, на досуге, если будет время.

PS. Обработка ошибок и определения переменных убраны для простоты чтения кода.

Опубликовано 04.08.2015 в 12:45 · Автор ivan · Ссылка
Рубрики: ABAP

Написать комментарий