Rfc error system failure

Random SAP BW Pack jobs, i.e.. Open Hub extract jobs and BW Load jobs, fail with the following error at the job startup phase, the problem jobs run fine if re-run without any job modification. Item #: 11 Event ID: 11 Timestamp:: 2011-11-11 07:03:01 Type: Fatal User Name: dsadm Message:: IN_DSO_CS_ZXX..T_ZXX_001: RFC_ERROR_SYSTEM_FAILURE: See RFC trace file or SAP system log for more details (group 104)

Problem

Random SAP BW Pack jobs, i.e.. Open Hub extract jobs and BW Load jobs, fail with the following error at the job startup phase, the problem jobs run fine if re-run without any job modification.

Item #: 11
Event ID: 11
Timestamp:: 2011-11-11 07:03:01
Type: Fatal
User Name: dsadm
Message:: IN_DSO_CS_ZXX..T_ZXX_001: RFC_ERROR_SYSTEM_FAILURE: See RFC trace file or SAP system log for more details (group 104)

Cause

Logon to SAP system failed due to time-out.

Diagnosing The Problem

Get the RFC trace for the failing job (cf IBM technote 1408720 on how to get RFC trace), and check if the SAP logon check function RfcOpenEx failed due to time-out.

>>> RfcOpenEx
Got following connect_param string:
CLIENT=100 USER=usr1 PASSWD=******* LANG=EN TRACE=0 ASHOST=10.10.10.10 SYSNR=10
Send RFCHEADER: 01/BIG/IEEE/SPACE/1100
Send UNICODE-RFCHEADER: cp:1100/ce:IGNORE/te:REJECT/cs:1/rc:0x00000023
UUID: send_rfcuuid {4EA9D4D8-D4D7-E02A-0200-00000A220EA9}

>>> Logon check: calling RFCPING

>>> RfcCall [1] …
*> RfcCall
FUNCTION RFCPING
handle = 1
parameter = <NULL>
tables = <NULL>
UUID: RfcCallNew send the uuid to the partner {4EA9D4D8-D4D7-E02A-0200-00000A220EA9}
>>>> [1] <unknown> : EXT <ac: 3> L 10.34.14.163 >>> WRITE (34312533)
-{4EA9D4D8-D4D7-E02A-0200-00000A220EA9}

<* RfcCall [1] : returns 0:RFC_OK
>>> Timeout during logon check

*> rfcClose called by RFC-Library in file: rfcext_mt.c, line: 568
handle = 1

<* rfcClose

<<< RfcOpenEx failed

Resolving The Problem

Logon failure due to time-out means either the network response is slow or the SAP Server response is slow (for example due to server load), so help is require from SAP Support.

There is a SAP environment variable, RFC_CONNECT_TIMEOUT, to control the SAP logon time-out period which is 60 seconds by default. Setting this variable to a larger value like 120 or 180 will reduce the chance of a time-out occurring.

  • To set it at the DataStage instance level, add the following lines to the $DSHOME/dsenv file and restart the DataStage Engine.

    RFC_CONNECT_TIMEOUT=<timeout_in_seconds> ## replace <…> with number of seconds

    export RFC_CONNECT_TIMEOUT

  • Or, to set the environment variable for a specific DataStage project, add the variable as a user defined environment variable in DataStage Administrator for that specific DataStage project.

Related Information

[{«Product»:{«code»:»SSZJPZ»,»label»:»IBM InfoSphere Information Server»},»Business Unit»:{«code»:»BU059″,»label»:»IBM Software w/o TPS»},»Component»:»Pack for SAP BW»,»Platform»:[{«code»:»PF002″,»label»:»AIX»},{«code»:»PF010″,»label»:»HP-UX»},{«code»:»PF016″,»label»:»Linux»},{«code»:»PF027″,»label»:»Solaris»},{«code»:»PF033″,»label»:»Windows»}],»Version»:»Version Independent»,»Edition»:»»,»Line of Business»:{«code»:»LOB10″,»label»:»Data and AI»}}]

REPORT  ztst_call_async_rfc.

PARAMETERS: p_para TYPE char1 DEFAULT ‘X’ AS CHECKBOX.

TYPES: BEGIN OF t_tasklist,

         taskname(4) TYPE C,        » Задача

         RESULT      TYPE char50,   » Статус обработки

      END OF t_tasklist.

DATA:

      lv_calls TYPE I VALUE 10,               » Количество запусков функции

      lv_max_tasks TYPE I,                    » Переменная для хранения максимального числа задач

      lv_free_tasks TYPE I,                   » Переменная для хранения числа свободных задач

      lv_number_of_tasks_in_use TYPE I,       » Количество задач в работе

      lv_started_rfc_calls TYPE I VALUE 0,    » Кол-во запущенных задач

      lv_finished_rfc_calls TYPE I VALUE 0,   » Кол-во завершенных задач

      lv_exception_flag(1) TYPE C,            » Флаг ошибки запуска задачи из-за нехватки ресурсов

      lv_taskname(4) TYPE N VALUE ‘0001’,     » Имя задачи

      lt_tasklist TYPE TABLE OF t_tasklist.   » Журнал обработки RFC вызовов.

DATA: » Для обработки времени работы

      lv_start_time TYPE timestampl,

      lv_end_time   TYPE timestampl,

      lv_diff       TYPE timestampl.

FIELDSYMBOLS: <fs_tasklist> TYPE t_tasklist.

START-OF-SELECTION.

  IF p_para EQ ‘X’.

    GET TIME STAMP FIELD lv_start_time.

* Получение максимального числа задач и кол-во свободных для использования задач.

    CALL FUNCTION ‘SPBT_INITIALIZE’

      EXPORTING

        group_name                     = »

      IMPORTING

        max_pbt_wps                    = lv_max_tasks

        free_pbt_wps                   = lv_free_tasks

      EXCEPTIONS

        invalid_group_name             = 1

        internal_error                 = 2

        pbt_env_already_initialized    = 3

        currently_no_resources_avail   = 4

        no_pbt_resources_found         = 5

        cant_init_different_pbt_groups = 6

        OTHERS                         = 7.

    IF sysubrc <> 0.

      MESSAGE ID symsgid TYPE symsgty NUMBER symsgno

              WITH symsgv1 symsgv2 symsgv3 symsgv4.

    ELSE.

      WRITE : / ‘Макисмальное число задач для выполнения параллельно обработки: ‘, 80 lv_max_tasks RIGHTJUSTIFIED.

      WRITE : / ‘Доступное кол-во задач: ‘, 50 lv_free_tasks RIGHTJUSTIFIED.

      ULINE.

      DO lv_calls TIMES.

        PERFORM call_rfc. » Запуск RFC задачи

        » call_rfc — запускает на выполнение RFC функцию в отдельном задаче (асинхронно),

        » в случае если нет свободных задач, или произошла ошибка выделения задачи,

        » ожидает пока не завершаться предыдущие задачи, после завершения продолжает данный цикл.

      ENDDO.

      » Последняя задержка пока не отработают все «последние» задачи.

      WAIT UNTIL lv_finished_rfc_calls = lv_calls.

      SKIP 2.

      WRITE : / ‘Журнал работы RFC функций:’.

      ULINE.

      LOOP AT lt_tasklist ASSIGNING <fs_tasklist>.

        WRITE : / <fs_tasklist>taskname,

                  <fs_tasklist>RESULT.

      ENDLOOP.

      SKIP.

      GET TIME STAMP FIELD lv_end_time.

      lv_diff = lv_end_time lv_start_time.

      WRITE: /(50) ‘Время работы’, lv_diff.

    ENDIF.

  ELSE.

    GET TIME STAMP FIELD lv_start_time.

    » Запуск функции в последовательной обработке

    DO lv_calls TIMES.

      CALL FUNCTION ‘Z_PAR_TEST’

        EXPORTING

          COUNT  = 2

        EXCEPTIONS

          OTHERS = 99.

    ENDDO.

    GET TIME STAMP FIELD lv_end_time.

    lv_diff = lv_end_time lv_start_time.

    WRITE: /(50) ‘Время работы’, lv_diff.

  ENDIF.

*&———————————————————————*

*& Form call_rfc

*&———————————————————————*

* text

*———————————————————————-*

FORM call_rfc.

  ADD 1 TO lv_number_of_tasks_in_use.

* Внимание: количество свободных задач для параллельной обработки делится между всеми

* пользователями, крайне не желательно использовать все (lv_free_tasks) для расчётов,

* их количество настраивается в тр. RZ12. В случае если все свободные задачи заняты кем

* то, программа выдаст сообщение об ошибке (Нехватке ресурсов ПФЗ), после вызова SPBT_INITIALIZE

  » Если количество процессов в работе будет превышать кол-во свободных задач,

  » остановим программу на ожидание освобождения задач.

  IF lv_number_of_tasks_in_use > lv_free_tasks.

    WRITE : / ‘Ожидаем пока завершатся предыдущие задачи’.

    WAIT UNTIL lv_number_of_tasks_in_use < lv_free_tasks.

  ENDIF.

  CALL FUNCTION ‘Z_PAR_TEST’

    STARTING NEW TASK lv_taskname

    «DESTINATION IN GROUP DEFAULT

    PERFORMING receive_results_from_rfc ON END OF TASK

    EXPORTING

      COUNT           = 2

* Так как используется асинхронный вызов RFC параметры импорта здесь не указываются,

* результат работы будет получаен в форме receive…

    EXCEPTIONS

      communication_failure = 1

      system_failure        = 2

      resource_failure      = 3.

* Чтобы узнать на каком сервере приложений будет запущена задача, необходимо сразу после запуска

* воспользоваться ФМ — SPBT_GET_PP_DESTINATION

* Чтобы исключить выполнение задачи на полученном сервере приложений используется ФМ: SPBT_DO_NOT_USE_SERVER

*

* Администрирование групп параллельной обработки выполняется через транзакцию — RZ12

* Мануал по этому делу тут: http://help.sap.com/saphelp_nw04/helpdata/en/fa/096e92543b11d1898e0000e8322d00/frameset.htm

* Пример обработки:

** 1 — system crash occured on the receiving side

** 2 — connection or communication problem with RFC-Destination

* CALL FUNCTION ‘SPBT_GET_PP_DESTINATION’

* IMPORTING rfcdest = lf_rfcdest.

*

* CALL FUNCTION ‘SPBT_DO_NOT_USE_SERVER’

* EXPORTING server_name = lf_server

* EXCEPTIONS

* invalid_server_name = 1

* no_more_resources_left = 2

* pbt_env_not_initialized_yet = 3

* OTHERS = 4.

* IF sy-subrc <> 0.

* cf_task_failure = chars. «e-message -> missing log

* EXIT.

* ENDIF.

  CASE sysubrc.

    WHEN 0.

      WRITE : / ‘Запущена новая задача с именем: ‘, lv_taskname.

      APPEND INITIAL LINE TO lt_tasklist ASSIGNING <fs_tasklist>.

      <fs_tasklist>taskname = lv_taskname.

      lv_started_rfc_calls = lv_started_rfc_calls + 1.

      ADD 1 TO lv_taskname.

    WHEN 1 OR 2.           «Communications failure

* Означает что сервер приложений не доступен; нет необходимости обрабатывать данное исключение,

    WHEN 3.                » Нет свободных задач, ожидаем.

      IF lv_exception_flag = SPACE.

        lv_exception_flag = ‘X’.

        WRITE : / ‘Нет доступных задач ждем пока освободятся…’.

        WAIT UNTIL lv_finished_rfc_calls >= lv_started_rfc_calls.

      ELSE.

        WRITE : / ‘Повторное ожидание освобождения задач…’.

        WAIT UNTIL lv_finished_rfc_calls >= lv_started_rfc_calls.

        IF sysubrc = 0.   » Ожидание было успешным

          CLEAR lv_exception_flag.

        ELSE.              » Ожидание прервано, сбой в RFC вызове, прерывание обработки

          WRITE : / ‘RFC вызов прерван’.

          EXIT.

        ENDIF.

      ENDIF.

  ENDCASE.

ENDFORM.                    «call_rfc

*&———————————————————————*

*& Form receive_results_from_rfc

*&———————————————————————*

* text

*———————————————————————-*

* —>VALUE(P_TASKNAME) text

*———————————————————————-*

FORM receive_results_from_rfc USING VALUE(p_taskname).

  lv_number_of_tasks_in_use = lv_number_of_tasks_in_use 1.

* Обновить статус задачи

  READ TABLE lt_tasklist WITH KEY taskname = p_taskname ASSIGNING <fs_tasklist>.

  IF sysubrc = 0.

    <fs_tasklist>RESULT = ‘Задача успешно завершена’.

  ELSE.

    READ TABLE lt_tasklist WITH KEY taskname = lv_taskname ASSIGNING <fs_tasklist>.

    IF sysubrc = 0.

      <fs_tasklist>RESULT = ‘Ошибка в обработке задачи’.

    ENDIF.

  ENDIF.

* Получение результатов обработки функции, в данном случае ничего не получаем

  RECEIVE RESULTS FROM FUNCTION ‘Z_PAR_TEST’.

  lv_finished_rfc_calls = lv_finished_rfc_calls + 1.

ENDFORM.                    «RECEIVE_RESULTS_FROM_RFC

Ezoic

Ezoic

Get Example source ABAP code based on a different SAP table
  


SECRET
ARTICLE

SYSTEM_FAILURE: ‘Screen display without connection to user.’
In a

remote function call, one of the following messages is displayed for the RFC exception SYSTEM_FAILURE:
‘CPIC server sent screen <(> <)>P1 <(> <)>P2 (termination)’
(<(> <)>P1 = program name, <(> <)>P2 = screen number)
‘Screen display without connection to user.’

ABAP runtime error

On the RFC client: CALL_FUNCTION_REMOTE_ERROR
Long text: ‘CPIC server sending screen … (termination)’
On the RFC server: DYNPRO_SEND_IN_BACKGROUND
Long text: ‘Screen display without connection to user.’

Cause and Conditions
The system tried to display a screen or list using an RFC connection.
This error can occur in the following circumstances:

RFC communication between two ABAP systems or within an ABAP system. The following errors can occur:
If you run the calling program in a background process and the server program tries to output screens or lists, the communication is always broken, regardless of the user type. Make sure that the RFC server program always runs in a dialog process.
If you run the calling program in a dialog process, the action leads to the communication being terminated because the user has insufficient authorization. The user in the RFC connection is not of the type DIALOG. Check the user profile for the user type DIALOG (transaction SU01 or Tools -> Administration, Users -> User maintenance -> User). If the RFC user has the type CPIC, background, or BDC, the function module called would terminate as soon as it tries to display a screen or list.
If the RFC communication is between an ABAP system and an external program such as a C or Visual Basic program, the communication is always broken when a screen is output, regardless of the user type. The exception to this is if the external program has a SAP GUI (RFC with SAP GUI). For further information, consult the system log (transaction SM21) or the error message ‘Screen output without connection to user’. You can also refer to the dump analysis (transaction ST22).

Solution

In the case of RFC communication between two ABAP systems or within an SAP system, you can solve the problem as follows:
If you run the calling program in a background job, you must modify the function modules called so that they do not display any screens or lists.
If you run the calling program in a dialog process, use an RFC user with user type ‘Dialog’.
If the RFC communication is between an ABAP system and an external program that does not have RFC with SAP GUI, you must change the function modules called so that they do not display any screens or lists.

This is the error code :

Line 115: ERROR: RFC_ERROR_SYSTEM_FAILURE Error in module RSQL of the database interface.    NOTE: PROC SQL set option NOEXEC and will continue to check the syntax of statements. `

Error Log :

NOTE: Libref SAPENG was successfully assigned as follows: 
  Engine:        R3 
  Physical Name: PRORELOC
101        %rcSet(&syslibrc);
102        
103        %let etls_recnt = 0;
104        %macro etls_recordCheck;
105           %let etls_recCheckExist = %eval(%sysfunc(exist(SAPEng.CDPOS, DATA)) or
106                 %sysfunc(exist(SAPEng.CDPOS, VIEW)));
107        
108           %if (&etls_recCheckExist) %then
109           %do;
110              proc sql noprint;
111                 select count(*) into :etls_recnt from SAPEng.CDPOS;
112              quit;
113           %end;
114        %mend etls_recordCheck;
115        %etls_recordCheck;
MPRINT(ETLS_RECORDCHECK):   proc sql noprint;
MPRINT(ETLS_RECORDCHECK):   select count(*) into :etls_recnt from SAPEng.CDPOS;
ERROR: RFC_ERROR_SYSTEM_FAILURE
Error in module RSQL of the database interface.

Any idea why this happen ?
The table i tried to extract is called CDPOS. There is no error on other SAP table

Sandra Rossi's user avatar

Sandra Rossi

11.5k3 gold badges22 silver badges44 bronze badges

asked Aug 15, 2011 at 5:36

gensius's user avatar

1

RFC_ERROR_SYSTEM_FAILURE means that the RFC call went wrong, usually producing a short dump (transaction ST22) and/or system log entries (SM21). Check these logs to find out what exactly went wrong.

answered Oct 5, 2012 at 10:10

vwegert's user avatar

vwegertvwegert

18.3k3 gold badges37 silver badges56 bronze badges

RFC (Remote Function Call) — протокол обмена данными между системами (подробно о SAP RFC написано в курсе BC415). RFC применяются для интеграции SAP и не SAP систем, обработки данных в новой сессии, параллельной обработки данных и т.п.

Классификация RFC

  • Синхронный RFC или sRFC. Определяется с помощью дополнения DESTINATION. При вызове sRFC рабочий процесс приостанавливает свою работу пока вызываемый sRFC модуль не завершит свою работу. Вызов sRFC выполняется в отдельном DB LUW. При вызове sRFC в основном процессе происходит неявный COMMIT.
  • Асинхронные RFC – определяются с помощью дополнения STARTING NEW TASK. К ним относятся асинхронные (aRFC) и параллельные (pRFC) RFC вызовы. При асинхронном вызове, вызываемый модуль запускается в новом процессе и работает параллельно с основным рабочим процессом. Результат выполнения ФМ можно получить в функции обратной связи. Вызовы aRFC и pRFC выполняются в отдельных DB LUW.
  • Фоновые RFC – определяются с помощью дополнения IN BACKGROUND. К ним относятся транзакционные (tRFC), очередные (qRFC) и фоновые (bgRFC) RFC вызовы. ФМ работают независимо от основного процесса и начинают выполнение после команды COMMIT WORK. На все фоновые RFC создается один DB LUW. Результат фонового RFC нельзя передать в основной процесс.


Вызывать по RFC можно любой функциональный модуль, который объявлен как «дистанционный».
Дистанционный функциональный модуль RFC

Целевая система

Целевая система определяется с помощью DESTINATION dest, где dest — название RFC соединения. Для настройки RFC соединений используется транзакция SM59. Если в качестве dest передать пустую строку, то функция будет выполнена локально. В качестве dest можно передать ‘NONE’ или ‘BACK’.

  • DESTINATION ‘NONE’ — вызывает запуск функционального модуля в отдельном сеансе пользователя на том же сервере приложений, что и вызывающая программа.
  • DESTINATION ‘BACK’ — вызывает запуск функционального модуля в системе, из которой был функциональный модуль. Используется для этого обратного вызова в синхронных RFC.

Исключения

В RFC функциях, помимо запрограммированных исключений, можно обработать системные исключения:

  • COMMUNICATION_FAILURE – возникает когда связь с сервером не установлена либо когда соединение было прервано.
  • SYSTEM_FAILURE – возникает когда на удаленной системе возникла ошибка.

Примечание
Системные исключения COMMUNICATION_FAILURE и SYSTEM_FAILURE можно объявить с MESSAGE msg. Тогда, при наступлении исключения в msg вернется любое сообщение из целевой системы.

Синхронный RFC (sRFC)

При синхронном вызове RFC, рабочий процесс приостанавливает свою работу пока вызываемый модуль не завершит свою работу. Вызов выполняется в отдельном DB LUW. При вызове sRFC в основном процессе происходит неявный COMMIT. Поэтому вызовы sRFC не должны находиться между OpenSQL операторами, обновляющие БД.
При повторном вызове sRFC, глобальные данные группы функций вызываемого ФМ будут доступны до тех пор, пока не будет закрыто указанное соединение.
Если в sRFC вызывает CALL SCREEN, CALL TRANSACTION или отображение списка, то вызываемые экраны будут отображены в программе запустившей sRFC, но только если в настройках соединения разрешен диалоговый удаленный доступ, в противном случае возникнет исключение SYSTEM_FAILURE.

Пример ниже демонстрирует синхронный вызов RFC и обработку возможных видов исключений.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

REPORT z_test_rfc.

START-OF-SELECTION.

  PERFORM main.

FORM main.

  PERFORM call_rfc USING  1 ».        » Локальный вызов

  PERFORM call_rfc USING  1 ‘NONE’.    » Вызов в новой сессии

  PERFORM call_rfc USING  0 ‘NONE’.    » Ожидаем определенное исключение

  PERFORM call_rfc USING  1 ‘UNKNOWN’. » RFC не существует

  PERFORM call_rfc USING 1 ‘NONE’.    » Ожидаем ошибку на удаленной системе

ENDFORM.

FORM call_rfc USING iv_foo TYPE i

                    iv_rfc TYPE rfcdest.

  DATA lv_msg TYPE c LENGTH 80.

  DATA lv_foo TYPE i.

  DATA lv_bar TYPE i.

  CALL FUNCTION ‘Z_TEST_RFC’ DESTINATION iv_rfc

    EXPORTING

      iv_foo                = iv_foo

    IMPORTING

      ev_bar                = lv_bar

    EXCEPTIONS

      communication_failure = 1 MESSAGE lv_msg

      system_failure        = 2 MESSAGE lv_msg

      wrong_input           = 3.

  CASE sysubrc.

    WHEN 0.

      WRITE: / ‘Успешно выполнено.’.

    WHEN 1.

      WRITE: / ‘Исключение COMMUNICATION_FAILURE:’, lv_msg.

    WHEN 2.

      WRITE: / ‘Исключение SYSTEM_FAILURE:’, lv_msg.

    WHEN 3.

      WRITE: / ‘Исключение функционального модуля WRONG_INPUT.’.

  ENDCASE.

ENDFORM.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

FUNCTION z_test_rfc.

*»———————————————————————-

*»*»Локальный интерфейс:

*»  IMPORTING

*»     VALUE(IV_FOO) TYPE  I

*»  EXPORTING

*»     VALUE(EV_BAR) TYPE  I

*»  EXCEPTIONS

*»      WRONG_INPUT

*»———————————————————————-

  IF iv_foo GT 0.

    ev_bar = 1.

  ENDIF.

  IF iv_foo EQ 0.

    RAISE wrong_input.

  ENDIF.

  IF iv_foo LT 0.

    MESSAGE e126(00). » Введите только положительные значения

  ENDIF.

ENDFUNCTION.

Результат
Пример вызова синхронного RFC

Аинхронный RFC (aRFC)

При асинхронном вызове RFC, вызываемый модуль запускается в новом процессе и работает параллельно с основным рабочим процессом. Вызов выполняется в отдельном DB LUW. Для запуска ФМ в асинхронном режиме необходимо вызвать ФМ с ключевыми словами STARTING NEW TASK <имя_задачи>.
Результат работы aRFC можно получить в функции обратного вызова, которая указывается с помощью ключевого слова PERFORMING <имя_процедуры> ON END OF TASK. При вызове aRFC из метода класса, функцией обратной связи может быть публичный метод, который определяется с помощью ключевого слова CALLING <имя_метода> ON END OF TASK. Указанные процедура или метод должны иметь один USING или IMPORTING параметр p_task типа clike, в который будет передаваться название задачи. Для получения данных из aRFC, внутри данной процедуры, используется обязательная команда RECEIVE RESULTS FROM FUNCTION <имя_функционального_модуля> c параметрами IMPORTING, TABLES, EXCEPTIONS которые будут переданы из aRFC.
Для ожидания выполнения aRFC вызовов используется команда WAIT UNTIL <условие>. Если условие выполняется, программа продолжит выполнение, если нет, то процесс будет ждать окончания выполнения следующего aRFC, пока условие не будет выполнено или не будут выполнены все aRFC вызовы.
В aRFC доступно системное исключение RESOURCE_FAILURE. Оно возникает если на сервере нет свободных ресурсов.

Пример ниже демонстрирует вызов нескольких aRFC и возврат результата в основной процесс. Функциональный модуль Z_TEST_RFC взят из примера sRFC.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

REPORT z_test_rfc.

TYPES:

  BEGIN OF gts_task,

    task    TYPE c LENGTH 5,

    foo     TYPE c LENGTH 5,

    bar     TYPE c LENGTH 5,

    subrc   TYPE c LENGTH 5,

    message TYPE text80,

  END OF gts_task.

DATA gv_tasks TYPE i.

DATA gt_tasks TYPE TABLE OF gts_task.

FIELDSYMBOLS <gs_tasks> TYPE gts_task.

START-OF-SELECTION.

  PERFORM main.

FORM main.

  CLEAR gv_tasks.

  PERFORM call_rfc USING  1 ».        » Локальный вызов

  PERFORM call_rfc USING  1 ‘NONE’.    » Вызов в новой сессии

  PERFORM call_rfc USING  0 ‘NONE’.    » Ожидаем определенное исключение

  PERFORM call_rfc USING  1 ‘UNKNOWN’. » RFC не существует

  PERFORM call_rfc USING 1 ‘NONE’.    » Ожидаем ошибку на удаленной системе

  WAIT UNTIL gv_tasks EQ 0.

  WRITE: / `Task `, `Foo  `, `Bar  `, `Subrc`, `Message`.

  LOOP AT gt_tasks ASSIGNING <gs_tasks>.

    WRITE: / <gs_tasks>task,

             <gs_tasks>foo,

             <gs_tasks>bar,

             <gs_tasks>subrc,

             <gs_tasks>message.

  ENDLOOP.

  WRITE / ‘Все задачи выполнены.’.

ENDFORM.

FORM call_rfc USING iv_foo TYPE i

                    iv_rfc TYPE rfcdest.

  DATA lv_msg TYPE c LENGTH 80.

  APPEND INITIAL LINE TO gt_tasks ASSIGNING <gs_tasks>.

  <gs_tasks>task = lines( gt_tasks ).

  <gs_tasks>foo = iv_foo.

  CALL FUNCTION ‘Z_TEST_RFC’ DESTINATION iv_rfc

    STARTING NEW TASK <gs_tasks>task

    PERFORMING callback ON END OF TASK

    EXPORTING

      iv_foo                = iv_foo

    EXCEPTIONS

      communication_failure = 1 MESSAGE lv_msg

      system_failure        = 2 MESSAGE lv_msg.

  IF sysubrc EQ 0.

    lv_msg = ‘Задача запущена’.

  ENDIF.

  <gs_tasks>subrc = sysubrc.

  <gs_tasks>message = lv_msg.

  ADD 1 TO gv_tasks.

ENDFORM.

FORM callback USING p_task TYPE clike.

  DATA lv_bar TYPE i.

  DATA lv_msg TYPE c LENGTH 80.

  READ TABLE gt_tasks ASSIGNING <gs_tasks>

    WITH KEY task = p_task.

  CHECK sysubrc EQ 0.

  RECEIVE RESULTS FROM FUNCTION ‘Z_TEST_RFC’

    IMPORTING

      ev_bar                = lv_bar

    EXCEPTIONS

      system_failure        = 1 MESSAGE lv_msg

      wrong_input           = 2.

  CASE sysubrc.

    WHEN 0.

      lv_msg = ‘Задача успешно выполнена.’.

    WHEN 2.

      lv_msg = ‘Исключение WRONG_INPUT.’.

  ENDCASE.

  <gs_tasks>subrc = sysubrc.

  <gs_tasks>message = lv_msg.

  <gs_tasks>bar = lv_bar.

  SUBTRACT 1 FROM gv_tasks.

ENDFORM.

Результат
Совокупный результат работы нескольких aRFC

Параллельный RFC (pRFC)

В ситуациях, когда требуется распараллелить выполнение пула однотипных операций, вместо aRFC рекомендуется использовать pRFC. Параллельный RFC работает схожим образом с aRFC и вызывается с помощью дополнения DESTINATION IN GROUP <имя_группы>. Группы pRFC настраиваются в RZ12. Если в качестве имени группы указать DEFAULT или SPACE, то вызов будет происходить на любой из определенных групп, в зависимости от их загруженности.
Для определения доступности ресурсов определенной группы можно воспользоваться ФМ SPBT_INITIALIZE.
Для определения сервера, на котором будет выполняться задача pRFC необходимо вызывать ФМ SPBT_GET_PP_DESTINATION сразу же после запуска pRFC.
Чтобы исключить конкретный сервер из дальнейшего использования для задач параллельной обработки (например, при исключении COMMUNICATION_FAILURE), необходимо использовать ФМ SPBT_DO_NOT_USE_SERVER.

Пример ниже демонстрирует параллельную обработку с учетом доступности ресурсов

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

REPORT z_test_rfc.

TYPES:

  BEGIN OF gts_task,

    task   TYPE c LENGTH 5,

    input  TYPE i,

    result TYPE i,

  END OF gts_task.

DATA gv_tasks TYPE i.

DATA gt_tasks TYPE TABLE OF gts_task.

START-OF-SELECTION.

  PERFORM main.

FORM main.

  DATA lv_total TYPE i.

  DATA lv_free TYPE i.

  FIELDSYMBOLS <ls_tasks> TYPE gts_task.

  CALL FUNCTION ‘SPBT_INITIALIZE’

    EXPORTING

      group_name                     = space

    IMPORTING

      max_pbt_wps                    = lv_total » Число рабочих процессов в группе

      free_pbt_wps                   = lv_free  » Число доступных процессов в группе

    EXCEPTIONS

      invalid_group_name             = 1 » Неизвестная группа (см. RZ12)

      internal_error                 = 2 » Внутренняя ошибка SAP (см. SM21)

      pbt_env_already_initialized    = 3 » Группа уже инициализирована

      currently_no_resources_avail   = 4 » Нет доступных ресурсов

      no_pbt_resources_found         = 5 » В группе нет серверов с процессами > 2

      cant_init_different_pbt_groups = 6 » Другая группа уже была инициализирована ранее

      OTHERS                         = 7.

  IF sysubrc <> 0.

    MESSAGE ID symsgid TYPE symsgty NUMBER symsgno

               WITH symsgv1 symsgv2 symsgv3 symsgv4.

  ENDIF.

  » Запуск пула однотипных задач

  DO 10 TIMES.

    PERFORM proc USING syindex.

  ENDDO.

  WAIT UNTIL gv_tasks EQ 0.

  WRITE: / `Task`, `      Input`, `     Result`.

  LOOP AT gt_tasks ASSIGNING <ls_tasks>.

    WRITE: / <ls_tasks>task,

             <ls_tasks>input,

             <ls_tasks>result.

  ENDLOOP.

  WRITE / ‘Все задачи выполнены.’.

ENDFORM.

FORM proc USING VALUE(iv_input) TYPE i.

  DATA lv_tasks_run TYPE i.

  DATA lv_rfcdest TYPE rfcsirfcdest.

  DATA lv_msg TYPE c LENGTH 80.

  FIELDSYMBOLS <ls_tasks> TYPE gts_task.

  APPEND INITIAL LINE TO gt_tasks ASSIGNING <ls_tasks>.

  <ls_tasks>task = lines( gt_tasks ).

  <ls_tasks>input = iv_input.

  lv_tasks_run = gv_tasks.

  DO.

    CALL FUNCTION ‘Z_TEST_RFC’

      STARTING NEW TASK <ls_tasks>task

      DESTINATION IN GROUP DEFAULT

      PERFORMING callback ON END OF TASK

      EXPORTING

        iv_input              = iv_input

      EXCEPTIONS

        communication_failure = 1 MESSAGE lv_msg

        system_failure        = 2 MESSAGE lv_msg

        resource_failure      = 3.

    CASE sysubrc.

      WHEN 0.

        » Задача успешно запущена

        ADD 1 TO gv_tasks.

        EXIT.

      WHEN 1 OR 2.

        » Получаем имя сервера

        CALL FUNCTION ‘SPBT_GET_PP_DESTINATION’

          IMPORTING

            rfcdest = lv_rfcdest.

        » И исключаем его из параллельной обработки

        CALL FUNCTION ‘SPBT_DO_NOT_USE_SERVER’

          EXPORTING

            server_name = lv_rfcdest.

    ENDCASE.

    » Ждем пока не осводятся ресурсы

    WAIT UNTIL gv_tasks LT lv_tasks_run UP TO 1 SECONDS.

  ENDDO.

ENDFORM.

FORM callback USING p_task TYPE clike.

  FIELDSYMBOLS <ls_tasks> TYPE gts_task.

  READ TABLE gt_tasks ASSIGNING <ls_tasks>

    WITH KEY task = p_task.

  CHECK sysubrc EQ 0.

  RECEIVE RESULTS FROM FUNCTION ‘Z_TEST_RFC’

    IMPORTING

      ev_result = <ls_tasks>result.

  SUBTRACT 1 FROM gv_tasks.

ENDFORM.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

FUNCTION z_test_rfc.

*»———————————————————————-

*»*»Локальный интерфейс:

*»  IMPORTING

*»     VALUE(IV_INPUT) TYPE  I

*»  EXPORTING

*»     VALUE(EV_RESULT) TYPE  I

*»———————————————————————-

  DATA lv_sec TYPE i.

  CALL FUNCTION ‘RANDOM_I4’

    EXPORTING

      rnd_min   = 3

      rnd_max   = 5

    IMPORTING

      rnd_value = lv_sec.

  WAIT UP TO lv_sec SECONDS. » Имитация работы длительной операции

  ev_result = iv_input * iv_input.

ENDFUNCTION.

Результат работы pRFC с учетом доступности ресурсов
Результат pRFC

Примечание
Если в pRFC вы используете алгоритм, требующий отдельной сессии (например пакетный ввод), то полагаться на исключение RESOURCE_FAILURE будет некорректно. Для определения максимального числа доступных процессов можно воспользоваться ФМ TH_USER_INFO.

DATA lv_act_sessions TYPE i.

DATA lv_max_sessions TYPE i.

DATA lv_free_sessions TYPE i.

CALL FUNCTION ‘TH_USER_INFO’

  IMPORTING

    act_sessions = lv_act_sessions

    max_sessions = lv_max_sessions.

lv_free_sessions = lv_max_sessions lv_act_sessions.

SAP Help на тему параллельной обработки.

Транзакционный RFC (tRFC)

При запуски tRFC основной процесс продолжает работу. Запуск tRFC осуществляется с помощью дополнения IN BACKGROUND TASK. Выполнение tRFC начинается после вызова COMMIT WORK либо после вызова ФМ START_OF_BACKGROUNDTASK. Для всех tRFC создается один DB LUW аналогично модулям обновления, это дает возможным сделать ROLLBACK во всех tRFC если возникнет ошибка хотя бы в одном tRFC. В отличие от aRFC и pRFC, результат tRFC нельзя вернуть в программу через RECEIVE RESULTS FROM FUNCTION.
Использование дополнения AS SEPARATE UNIT функциональный модуль выполняется в отдельном контексте, в котором на глобальные данные группы функций не влияют предыдущие вызовы. Это означает, что при использовании одного и того же DESTINATION для нескольких вызовов tRFC, принадлежащих к одной и той же группе функций, глобальные данные этой группы функций доступны всем последующим tRFC.

Пример запуска tRFC

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

REPORT z_test_rfc.

START-OF-SELECTION.

  PERFORM main.

FORM main.

  » Глобальные переменные общие для всех tRFC

  DO 10 TIMES.

    CALL FUNCTION ‘Z_TEST_RFC’

      IN BACKGROUND TASK

      EXPORTING

        iv_input = syindex.

  ENDDO.

  » Для каждого tRFC свой набор глобальных переменных

  DO 10 TIMES.

    CALL FUNCTION ‘Z_TEST_RFC’

      IN BACKGROUND TASK

      AS SEPARATE UNIT

      EXPORTING

        iv_input = syindex.

  ENDDO.

  » Запуск всех tRFC

  COMMIT WORK.

ENDFORM.

SAP Help на тему tRFC.

Очередный RFC (qRFC)

Очередный RFC — вариант tRFC, учитывающий порядок вызова модулей. В случае tRFC очередность выполнения модулей может не совпадать с порядком их вызовов. Для установки очередности необходимо перед каждым вызовом qRFC вызвать ФМ TRFC_SET_QUEUE_NAME с указанием имени очереди.

Пример ниже демонстрирует выполнение qRFC в том же порядке, в котором были вызваны модули

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

REPORT z_test_rfc.

START-OF-SELECTION.

  PERFORM main.

FORM main.

  DATA lv_index TYPE i.

  DATA lv_qname TYPE trfcqoutqname.

  DO 10 TIMES.

    lv_index = syindex.

    lv_qname = ‘Q’ && lv_index.

    CALL FUNCTION ‘TRFC_SET_QUEUE_NAME’

      EXPORTING

        qname = lv_qname.

    CALL FUNCTION ‘Z_TEST_RFC’

      IN BACKGROUND TASK

      EXPORTING

        iv_input = lv_index.

  ENDDO.

  COMMIT WORK.

ENDFORM.

Фоновый RFC (bgRFC)

Фоновый RFC является технологией преемника tRFC и qRFC. SAP настоятельно рекомендует использовать bgRFC вместо tRFC и qRFC. Вызов bgRFC осуществляется с помощью дополнения IN BACKGROUND UNIT <oref>, где oref — ссылка на экземпляр класса, реализующий интерфейс IF_BGRFC_UNIT. Объект содержит всю информацию, требуемую для удаленного вызова функции, включая DESTINATION, тип вызова (tRFC или qRFC), количество очередей. Если один и тот же объект используется для нескольких вызовов, все вызываемые функциональные модули выполняются в одном модуле. И наоборот, несколько объектов этого типа могут использоваться параллельно в одном внутреннем сеансе, что обеспечивает параллельную обработку.
Примеры использования bgRFC можно найти в SAP через журнал использования по интерфейсу IF_BGRFC_UNIT.

Понравилась статья? Поделить с друзьями:
  • Roblox 13 как изменить возраст
  • Rns 510 swl error
  • Rns 510 hdd error 255
  • Rnosmodule java 31 error method does not override or implement a method from a supertype
  • Rmshutdown failed with error 351