为什么有些 RFC 受到最大限制。 GUI 会话数?

问题描述 投票:0回答:2

通过 RFC 多次调用函数

ME_INFORECORD_MAINTAIN_MULTI
失败,并显示短转储“达到 GUI 会话的最大数量”,但以相同方式调用时其他函数似乎不受会话限制。

我可以并行调用此函数的数量取决于我当前打开的 GUI 会话(SAP GUI 窗口)的数量。

例如,以下代码在 5 次调用后失败(我在发生转储的行的开头添加了

>>>
):

FORM CALL_BAPI_INFORECORD.
lv_taskname = |PIR-{ lv_sentjobs WIDTH = 3 ALIGN = RIGHT PAD = '0' }|.
DATA: lv_retry TYPE ABAP_BOOL.
lv_retry = ABAP_TRUE.

WHILE lv_retry = ABAP_TRUE.
  lv_retry = ABAP_FALSE.
  CALL FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
    STARTING NEW TASK lv_taskname
    DESTINATION IN GROUP DEFAULT
    PERFORMING RETURN_BAPI_INFORECORD ON END OF TASK
    [...]
  EXCEPTIONS
    system_failure        = 1 MESSAGE lv_exceptionmsg
    communication_failure = 2 MESSAGE lv_exceptionmsg
    resource_failure      = 3
CASE sy-subrc.
  WHEN 0.
    lv_sentjobs = lv_sentjobs + 1.
  WHEN 1 OR 2.
    MESSAGE lv_exceptionmsg TYPE 'I'.
    WRITE: / lv_taskname, ':', lv_exceptionmsg.
  WHEN 3.
    WAIT FOR ASYNCHRONOUS TASKS UNTIL lv_recvjobs = lv_sentjobs UP TO 300 SECONDS.
    lv_retry = ABAP_TRUE.
  WHEN OTHERS.
    MESSAGE 'Unkown error.' TYPE 'I'.
ENDCASE.
ENDWHILE.
ENDFORM.

FORM RETURN_BAPI_INFORECORD USING TASKNAME.
  DATA INFO LIKE RFCSI.
>>> RECEIVE RESULTS FROM FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
    IMPORTING
      RFCSI_EXPORT = INFO
      RETURN = GT_ME_INFORECORD_RETURN.
ENDFORM.

...但是以下代码在 10 个并行调用下运行良好:

FORM CALL_BAPI_MATERIAL.
lv_taskname = |MAT-{ lv_sentjobs WIDTH = 3 ALIGN = RIGHT PAD = '0' }|.
DATA: lv_retry TYPE ABAP_BOOL.
lv_retry = ABAP_TRUE.

WHILE lv_retry = ABAP_TRUE.
lv_retry = ABAP_FALSE.
  CALL FUNCTION 'BAPI_MATERIAL_SAVEREPLICA'
    STARTING NEW TASK lv_taskname
    DESTINATION IN GROUP DEFAULT
    PERFORMING RETURN_BAPI_MATERIAL ON END OF TASK
    [...]
  EXCEPTIONS
    system_failure        = 1 MESSAGE lv_exceptionmsg
    communication_failure = 2 MESSAGE lv_exceptionmsg
    resource_failure      = 3.

CASE sy-subrc.
  WHEN 0.
    lv_sentjobs = lv_sentjobs + 1.
  WHEN 1 OR 2.
    MESSAGE lv_exceptionmsg TYPE 'I'.
    WRITE: / lv_taskname, ':', lv_exceptionmsg.
  WHEN 3.
    WAIT FOR ASYNCHRONOUS TASKS UNTIL lv_recvjobs = lv_sentjobs UP TO 300 SECONDS.
    lv_retry = ABAP_TRUE.
  WHEN OTHERS.
    MESSAGE 'Unknown error.' TYPE 'I'.
ENDCASE.
ENDWHILE.
ENDFORM.

FORM RETURN_BAPI_MATERIAL USING TASKNAME.
  DATA INFO LIKE RFCSI.
  RECEIVE RESULTS FROM FUNCTION 'BAPI_MATERIAL_SAVEREPLICA'
    IMPORTING
      RFCSI_EXPORT = INFO
      RETURNMESSAGES = GT_BAPI_SAVEREPLICA_RETURN.
ENDFORM.

这是转储发生时的堆栈。

为什么函数 ME_INFORECORD_MAINTAIN_MULTI 受到 GUI 会话限制以及如何绕过它?

abap saprfc
2个回答
0
投票

在某些情况下,功能模块会在内部引发 GUI 会话(“ABAP 会话”)。这是由调用对话框模块的内部处理引起的。

“在 aRFC 处理中调用 dynpro 时,会在 RFC 客户端中打开额外的 ABAP 会话(另请参阅 RFC 对话交互。不能超过 ABAP 会话的最大数量,如果有更多,则会显示错误消息。最大数量会话数在配置文件参数 rdisp/max_alt_modes 中定义,并且不能大于 16。"

https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abapcall_function_starting.htm


-1
投票

您确定有误吗

“已达到最大 GUI 会话数”

由于函数调用?

CALL FUNCTION 'BAPI_MATERIAL_SAVEREPLICA'
    STARTING NEW TASK lv_taskname
    DESTINATION IN GROUP DEFAULT
    PERFORMING RETURN_BAPI_MATERIAL ON END OF TASK

您是否在调用函数语句中包含了异常?

    exceptions   resource_failure =  1
                 others         = 2.

当群组中不再有免费资源时,您将收到“resource_failure”异常。 根据您的描述,我预计会出现资源失败错误。

检查您正在使用的服务器组的 Rz12 中的设置。 “启动新任务”(通过 rfc)的功能会检查这些参数设置。 因此,如果服务器“忙”,则调用失败。

这是一个基本的 shell 程序,可用于测试并行代码行为。

REPORT ZPARA. data t type i. parameters: cnt type i default 10000000, packets type i default 10, para as checkbox default 'X', waittime type i default 1, rfcgroup like rzllitab-classname . data total type f. data splits type i. data mod type i. data packetsize type i. data: first type i. data: last type i. data: this_last type i. data: this_split type i. data: ret_splits type i. data: act_splits type i. data: taskname type num8 value 0. data: begin of task occurs 0, taskname type num8, uzeit like sy-uzeit, wpinfo TYPE WPINFO, end of task. data max_pbt_wps type i. data free_pbt_wps type i. start-of-selection. PERFORM classic_version. form classic_version. **** TO USE THIS CODE, * create a parallel(rfc) server group in RZ12. * create the function decribed below ************************************************** * set run time res low, so measurement in milli not microsecs. * we are measure BIG runs refresh task. set run time clock resolution low. get run time field t. total = 0. check cnt > 0. if packets = 0. packets = 5. endif. * splits calculated based on packet size splits = packets. PACKETSIZE = cnt div PACKETS. * is parallel mode selected if para = 'X'. * parallel processing MUST be initialized first. call function 'SPBT_INITIALIZE' exporting group_name = rfcgroup importing max_pbt_wps = max_pbt_wps free_pbt_wps = free_pbt_wps 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 sy-subrc <> 0. * if our group failed or the available processes was 0, * we would exit cleanly here. * for the demo, just bomb out. endif. last = 0. ret_splits = 0. act_splits = 0. * so for each split do splits times. * make a jobname taskname = taskname + 1. * work out which chunk we are processing * ie were are we up to ?? first = last + 1. this_last = first + packetsize - 1. * for info purposes record which split this_split = sy-index. * just in case we have the last split, * calculated adjust target end, if this_last > cnt. this_last = cnt. endif. * try a dispatch this split. * this is where more logic is needed. * here we set a max of a hundred tries to dispatch * something. IN VERY LARGE jobs, * a commit work and a more intelligent wait * might be appropriate. * we at least wait, 1 then 2 then 3... secs etc * until we get a look in. do 100 times. * inside a parallel ( new ) task * do a chunk of work. * NO importing parameters here. The result is returned * in the receiving function. * SPECIAL, extra, exceptions are available to control * success or otherwise of the dispatch. write: / 'Split ', this_split, 'dispatch at', sy-uzeit. call function 'Z_CHUNK' starting new task taskname destination in group rfcgroup performing finished on end of task exporting from_int = first to_int = this_last exceptions resource_failure = 1 others = 2. if sy-subrc = 0. * dispatch ok, record the fact and march on... act_splits = act_splits + 1. last = first + PACKETSIZE - 1. exit. " the retry until dispatched loop. else. write: 'No resource free'. write: / 'Split ', this_split, 'Waits ', waittime, 'secs at', sy-uzeit. * wait x seconds, each attempt waits successlively longer wait up to waittime seconds. endif. enddo. * Actual failure to dispatch is not captured in this version * your code should consider this issue. enddo. *** THE BIG ROUNDUP * we wait here until ALL splits are returned. * we do that by waiting until a return counter * equals the numbers of dispatches. * this wait does not wait indefinitely if a dispatch above * fails, since another continue point is NO oustanding * async tasks. *** wait until ret_splits >= act_splits. else. call function 'Z_CHUNK' exporting from_int = 1 to_int = cnt importing tot = total. endif. get run time field t. t = t / 1000. loop at task. write: / 'Received task', task-taskname, ' at ', task-uzeit, ' in WP:', task-WPINFO-WP_INDEX. endloop. write: / 'Parallel', para. write: / 'Time ms ', t left-justified. write: / 'Splits ', splits left-justified. write: / 'Total ', total left-justified. endform. *---------------------------------------------------------------------* * FORM finished * *---------------------------------------------------------------------* * ........ * *---------------------------------------------------------------------* * --> TASKNAME * *---------------------------------------------------------------------* form finished using taskname. data: ls_wpinfo type WPINFO. data l_tot type f. receive results from function 'Z_CHUNK' importing tot = l_tot wp_index = LS_WPINFO-WP_INDEX. * when receiving a task back, we get out result * and record that the task returned, by uping a counter. task-taskname = taskname. task-uzeit = sy-uzeit. task-WPINFO = LS_WPINFO. append task. total = total + l_tot. ret_splits = ret_splits + 1. endform. ***** * Create this function to test. FUNCTION Z_CHUNK IMPORTING VALUE(FROM_INT) TYPE I VALUE(TO_INT) TYPE I EXPORTING VALUE(TOT) TYPE F VALUE(WP_INDEX) TYPE WPINFO-WP_INDEX. data l_i type i. tot = 0. check to_int > from_int. l_i = from_int. while l_i <= to_int. tot = tot + l_i. l_i = l_i + 1. endwhile. CALL FUNCTION 'TH_GET_OWN_WP_NO' IMPORTING WP_INDEX = WP_INDEX . ENDFUNCTION.
    
© www.soinside.com 2019 - 2024. All rights reserved.