如何解决为什么某些 RFC 受到最大限制 GUI 会话的数量?
通过 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 会话的限制以及如何绕过它?
解决方法
你确定你出错了
“已达到最大 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 ','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.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。