Remote Function Call

Remote Function Call (RFC, удалённый вызов функций) – стандартный интерфейс для обмена данными между SAP и не SAP системами. Интерфейс передачи данных основан на CPI-C или TCP/IP. Стандартная справка по теме RFC или курс BC415.

Особенности RFC функций

  • Когда вы вызываете ФМ локально, он работает в том же рабочем процессе что и вызывающая программа. Если вы вызываете ФМ удаленно, он запускается в отдельном рабочем процессе (ЛЕР – LUW, логическая единица работы) если удаленная система является R/3 системой.
  • В качестве удаленной системы могут быть R/3 система, R/2 система или другая внешняя не SAP система, для не SAP систем существует специальная RFC-SDK библиотека, с помощью которой может быть реализован клиент-сервер для RFC.
  • При вызове RFC модуля, в программе его вызывающий срабатывает неявный DB Commit (исключение tRFC, qRFC, bgRFC). Поэтому вызовы RFC не должны находиться между OpenSQL операторами.
  • В интерфейсе ФМ RFC необходимо явно определять тип для каждого параметра, ссылки (LIKE) запрещены.

Настроить назначение для RFC вызова можно через транзакцию SM59 (Таблица RFCDES). Подробнее о настройке RFC соединений можно посмотреть в курсе BC415.

Назначение RFC вызовов

Назначение RFC вызова определяется с помощью ключевого слова DESTINATION. В качестве параметра может принимать имя удаленной системы, SPACE, NONE, BACK.

  • SPACE – локальный вызов ФМ (по умолчанию). В случае если не указать DESTINATION в параметрах вызова RFC, функция будет выполнена локально, как обычная без создания своего LUW.
  • NONE – Запуск происходит так же локально, основное отличие в том, что вызов доходит до указанного в настройках шлюза и регистрируется в качестве удаленного вызова. Создается свой DB LUW.
  • BACK – используется внутри синхронных RFC функций, для запуска RFC функций в той системе которая их вызвала.

  

Обработка исключений при вызовах RFC

При вызове RFC модуля могут возникать следующие исключения:

  • COMMUNICATION_FAILURE – возникает в том случае, когда не настроено соединение для указанной системы в поле DESTINATION, либо когда соединение не могло быть установлено.
  • SYSTEM_FAILURE – возникает в случае, если на удаленной системе не существует вызываемого модуля, либо в случае других неполадок в RFC вызовах.
  • RESOURCE_FAILURE – возникает при вызове асинхронных RFC, в случае если нет свободных ресурсов на сервере приложений группы.

Типы RFC функций:

  1. Синхронные RFC (sRFC) – при вызове sRFC рабочий процесс приостанавливает свою работу, до тех пор, пока не будет выполнен sRFC модуль. Модуль выполняется в отдельном DB LUW.

В случае, когда вы вызываете несколько sRFC подряд из одной группы функций, глобальные данные группы функций будут доступны до тех пор, пока не будет вызвана последняя функция из данной группы.

Если в sRFC внутри себя вызывает CALL SCREEN, CALL TRANSACTION или отображение списка, вызываемые экраны будут отображены в программе запустившей sRFC, но только если в SM59 указан диалоговый удаленный доступ, иначе система выдаст исключение SYSTEM_FAILURE.

  1. Асинхронные RFC вызовы (aRFC) – удаленная функция начинает работать параллельно сразу после её вызова, при этом рабочий процесс не приостанавливает свою работу. Асинхронный вызов срабатывает при вызове ФМ с ключевыми словами: STARTING NEW TASK <ИмяЗадачи>. Модуль выполняется в отдельном DB LUW. aRFC можно так же использовать в фоновом выполнении.

Для получения результатов работы aRFC необходимо при вызове указать на процедуру обработки результатов, задается она с помощью ключевого слова: PERFORMING <ИмяПроцедуры> ON END OF TASK. Процедура в качестве первого параметра должна содержать переменную, в которую будет записано имя задачи (имя данной переменной не имеет значения). Для получения данных из aRFC, внутри данной процедуры, используется обязательная команда (если ее не задать в процедуре, система выдаст исключение — COMMUNICATION_FAILURE): RECEIVE RESULTS FROM FUNCTION <ИмяARFC>, c параметрами IMPORTING, TABLES, EXCEPTIONS которые будут переданы из aRFC.

Процедура не должна иметь в своем теле операторы, прерывающие выполнение программы, такие как: CALL SCREEN, SUBMIT, COMMIT WORK, WAIT, RFC вызовы, сообщения с типами W и I.

Для ожидания выполнения aRFC вызовов существует ключевое слово WAIT UNTIL <Условие>. Если после вызова aRFC условие выполняется, программа сразу же начинает свое выполнение после WAIT UNTIL. В случае если не выполняется, программа снова проверяет условие. Данный процесс повторяется до тех пор, пока условие не будет выполнено или не будут выполнены все aRFC вызовы.

Пример программы запускающей 2 aRFC функции и ожидающей выполнение обоих:

Если в качестве имени задачи в вызове aRFC указать TASK3, условия выполнены не будут.

aRFC вызовы могут вызываться в одной SAP системе, но на разных серверах приложений, тем самым распределяя нагрузку между ними. Для распределения aRFC вызовов между серверами приложений служат так называемые RFC группы (тр. SM59). Для определения в какой именно группе вызывать aRFC служит ключевое слово – DESTINATION IN GROUP <ИмяГруппы>.  Если в качестве имени группы указать DEFAULT, вызов будет происходить на любой из определенных групп, в зависимости от их загруженности, если все группы будут заняты, система выдаст исключение – RESOURCE_FAILURE.

SAP Help на тему распараллеливания.

Пример распараллеливания вычислений с помощью групп:

aRFC вызовы так же как и sRFC могут вызывать внутри себя диалоги, но их использование в данном контексте выглядит сомнительно, более подробно рассмотрено в курсе (BC415).

  1. Транзакционные RFC (tRFC) – асинхронные и синхронные вызовы RFC отрабатывают каждый в своем DB LUW (ЛЕР), транзакционные RFC срабатывают в одном DB LUW, тем самым позволяют группировать их вызовы с возможностью отката в случае ошибок в одном из tRFC вызове. Запуск tRFC осуществляется с помощью ключевого слова IN BACKGROUND TASK. Программа, запустившая tRFC, не приостанавливает свою работу, вызов tRFC происходит тогда, когда программа вызовет COMMIT WORK. В момент вызова tRFC не происходит вызова неявного DB COMMIT. tRFC, так же как и aRFC вызываются асинхронно, однако получить результат работы этих функций как в aRFC невозможно. Для просмотра созданных tRFC-LUW служит транзакция SM58.

Все tRFC вызовы сохраняются в таблицах: ARFCSSTATE и ARFCSDATA. Если вы не хотите вызывать tRFC немедленно после COMMIT WORK, вы можете вызвать ФМ START_OF_BACKGROUNDTASK (до COMMITWORK) и задать время и дату запуска для накопленных tRFC вызовов.

После выполнения COMMIT WORK в случае успешного локального обновления (в рамках LUW основной программы),  накопленные данные создают фоновую задачу, в случае успешного выполнения этой задачи все данные из таблиц tRFC удаляются. Если задача не была выполнена, срабатывает механизм повтора или отката.

Так, например если связь с удаленной системой не была установлена, срабатывает автоматический повтор выполнения задания. По умолчанию количество повторов равно 30, интервал ожидания равен 15 минутам.

В случае если во втором из двух tRFC вызовов произошел сбой, сообщение с типом A или X или вызов исключения через RAISE после успешного выполнения первого происходит следующее:

  • Все изменения сделанные в текущем LUW (а он один на все tRFC) откатываются
  • Происходит запись в журнал вызова tRFC (тр. SM58)

Для принудительного отката всех изменений или отмены tRFC-LUW служит ФМ — RESTART_OF_BACKGROUNDTASK.

В случае если вызовы tRFC происходят на разных системах (DESTINATION ‘A’, DESTIONATION ‘B’), для каждой из них создается свой tRFC-LUW, вызовы tRFC группируются в зависимости от назначения.

Для вызова tRFC отдельно от остальных можно воспользоваться ключевым словом: AS SEPARATE UNIT.

Каждый tRFC-LUW имеет свой уникальный ID, для его получения можно использовать ФМ: ID_OF_BACKGROUNDTASK (вызывать перед COMMIT WORK). Используя данный ID можно определить статус для tRFC-LUW через ФМ — STATUS_OF_BACKGROUNDTASK.

  1. qRFC – RFC функции выполняемые в порядке очереди. При использовании tRFC мы не можем контролировать порядок запуска tRFC модулей, другими словами порядок их вызова может не соответствовать порядку их запуска. qRFC в отличие от tRFC, позволяют нам контролировать порядок их запуска.

Для размещения tRFC вызовов в порядке FIFO (первый пришел, первый вышел) необходимо перед каждым tRFC вызовом указывать имя очереди, делается это с помощью ФМ: TRFC_SET_QUEUE_NAME:

Имя очереди может содержать 24 символа, исключая % и *.

Для администрирования qRFC вместо транзакции SM58 используется транзакция — SMQ1. Таблица, в которой хранятся данные qRFC — TRFCQOUT.

  1. Фоновые RFC (bgRFC). SAP рекомендует использовать их вместо tRFC и qRFC для лучшей производительности. bgRFC, в отличие от tRFC и qRFC, позволяют приложениям записывать данные полученные позже от вызванных программ. Кроме того можно организовывать зависимые последовательности вызовов, так например вызов создающий входящую поставку будет выполнен только после выполнения вызова создающего закупочный заказ. bgRFC вызываются с помощью ключевого слова IN BACKGROUND UNIT <oref>, где <oref> — ссылка на класс реализующий интерфейс IF_BGRFC_UNIT.

Более подробная информация о bgRFC находится тут.

Транзакции, используемые при работе с RFC

  • ST22 – просмотр дампов, вызываемых RFC
  • SMGW – монитор шлюза RFC подключений
  • Журналы работы: на стороне вызовов – ST05, на стороне вызываемой системы SM59, на стороне шлюза – SMGW

BAPI функции

Для обмена бизнес данными, между SAP и не SAP системами, был создан так называемый Business Framework. Центральной его частью является хранилище бизнес объектов (BOR – Business Object Repository). Каждый бизнес объект обеспечивает объектно-ориентированный подход к хранению бизнес данных и работы с бизнес процессами. Например, вызывая методы бизнес объектов, мы тем самым манипулируем бизнес данными, за которые он отвечает, не заботясь о техническом вопросе (связях в таблицах и т.п.)

Бизнес объект состоит из следующих частей:

  • Технические данные – внутренний номер, номер релиза SAP системы, с которой он доступен и т.п.
  • Список интерфейсов, которые поддерживает объект – интерфейс определяет поведенческую структуру объекта
  • Ключевые поля – атрибуты, которые однозначно идентифицируют объект. (Номер закупочного заказа)
  • Атрибуты – могут быть как поля из базы данных, так и рассчитываемые во время работы с объектом (виртуальные), ссылки на другие объекты (Бизнес объект «Заказ на закупку» например, может иметь ссылки на объекты входящих поставок)
  • Методы – представляют собой вызовы R/3 транзакций, функциональных модулей или другого ABAP кода. BAPI как раз и представляют собой реализацию методов бизнес объектов.
  • События – используются в основном в Workflow. Например, сделать рассылку поставщикам при создании закупочного заказа.

BAPI – реализация метода бизнес объекта, представляет собой функциональный модуль RFC. BAPI могут вызываться как синхронно (COMMIT WORK AND WAIT), так и асинхронно т.е. ожидая выполнения работы функции или нет.

BAPI могут представлять различные действия над объектом:

  • Создание объекта
  • Запрос атрибутов объекта
  • Изменение атрибутов объекта

BAPI могут вызываться из различных приложений: офисных приложений (через VBA), JAVA и С++ программ и т.п.

Все BAPI после своей работы возвращают результат в виде внутренней таблицы с одной из структур: BAPIRETURN, BAPIRETURN1, BAPIRET1, BAPIRET2, BAPIRET1_FIX. В связи с этим в BAPI нет обработки исключений как в стандартных ФМ. Все эти структуры содержат в себе следующие поля:

  • TYPE – тип сообщения: S(uccess), E(rror), W(arning), I(nformation)
  • ID (класс сообщений)
  • NUMBER (номер сообщения в классе)
  • MESSAGE (текст сообщения)
  • MESSAGE_V1, MESSAGE_V2, MESSAGE_V3, MESSAGE_V4 (переменные сообщений)

Если транзакция выполнена успешно, то в таблице RETURN не будет существовать записей с типом ошибки «Е». Должно присутствовать сообщение с типом ошибки «S».

Обновление в BAPI всегда происходит в IN UPDATE TASK (см. документацию по ключевому слову IN UPDATE TASK или курс по обновлению БД – BC414). Внутри BAPI никогда не вызывается COMMIT WORK. Для подтверждения или отката LUW всегда должны использоваться ФМ: BAPI_TRANSCATION_COMMIT, BAPI_TRANSACTION_ROLLBACK, разница между данными ФМ и COMMIT WORK (ROLLBACK WORK) в том что они чистят внутренние переменные используемые при вызовах BAPI, если этого не делать могут возникать проблемы при повторном вызове BAPI. Все BAPI вызванные в программе до вызова BAPI_TRANSCATION_COMMIT (BAPI_TRANSCATION_ROLLBACK) вызываются в одном LUW. Для просмотра всех имеющихся в системе BAPI служит транзакция BAPI (запускает BAPI EXPLORER).

Курс, в котором рассматривается создание собственных BAPI — BC417.

  • Константин

    Благодарю, Михаил!

    Очень хорошо все расписано. Мне очень нравится читать Ваш блог, что-то узнаю новое, что-то вспоминаю. Так держать, успехов во всем!

    • Спасибо!

    • Xone:92

      Присоединяюсь — потрясающий блог! Много полезной новой информации, доступно и понятно изложено всё!
      Спасибо!!!

  • Зуфар

    Спасибо большое, Михаил!

    Грамотно и доходчиво, подкреплено примерами! После прочтения Ваших статей вопросов не возникает, разве что сам невнимательно прочел. Удачи!

  • Дмитрий Карпов

    Добрый день.

    По поводу отсутствия COMMIT’а в BAPI: COMMIT_CONTROL = ‘E’ не считается за COMMIT?

    • Добрый день.

      Честно говоря не знаю о чём Вы, видимо это специфика каких-то конкретных BAPI.