ABAP异步调用Function
调用语法:
CALL FUNCTION Remotefunction STARTING NEW TASK Taskname
DESTINATION IN GROUP {group|DEFAULT}
[{CALLING meth}|{PERFORMING subr} ON END OF TASK]
EXPORTING...
TABLES ...
CHANGING...
EXCEPTIONS...
Taskname:唯一值,多次调用需要生成不同唯一的Taskname;
DESTINATION Dest:指定application servers,Tcode:RZ12,查看最大支持并行数Max. Requests in Que;
[{CALLING meth}|{PERFORMING subr} ON END OF TASK]:设置回调子函数FORM,或回调方法。Method必须是公共Method,并且有输入参数p_task,类型clike;Subroutine必须Using p_task type clike。p_task其实就是调用时的Taskname。
EXPORTING...:输入参数
TABLES ...:输入输出Table类型参数
EXCEPTIONS...:默认三种Exception,resource_failure,当没有多余并行资源时,返回这个exception.
[EXCEPTIONS [exc1 = n1 exc2 = n2 ...]
[system_failure = ns [MESSAGE smess]]
[communication_failure = nc [MESSAGE cmess]]
[resource_failure = nr [MESSAGE rmess]]
[OTHERS = n_others]].
回调函数接收执行结果:
RECEIVE RESULTS FROM FUNCTION func
parameter list
[KEEPING TASK].
KEEPING TASK:当回调函数执行完后,保持连接,可以通过Taskname执行获得相同全局参数;
parameter list:异步函数调用参数
[IMPORTING p1 = a1 p2 = a2 ...]
[TABLES t1 = itab1 t2 = itab2 ...]
[EXCEPTIONS exc1 = n1 exc2 = n2 ... [MESSAGE mess]
[OTHERS = n_others]].
WAIT阻塞当前主逻辑执行,只有在有回调函数的function使用,阻塞主逻辑,当回调函数执行后,反复执行判断。
WAIT UNTIL log_exp [UP TO sec SECONDS].
示例1:使用类方法
"类方式异步调用function
CLASS zcl_parellel DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:main.
CLASS-METHODS:m_callback IMPORTING p_task TYPE clike.
PRIVATE SECTION.
TYPES:BEGIN OF s_task,
name TYPE char10,
lines TYPE i,
END OF s_task.
CLASS-DATA:lt_task TYPE TABLE OF s_task.
CLASS-DATA:ls_task LIKE LINE OF lt_task.
CLASS-DATA:lv_count_suc TYPE i.
ENDCLASS.
CLASS zcl_parellel IMPLEMENTATION.
"实现main函数
METHOD main.
DATA:lv_start TYPE i.
DATA:lv_name TYPE c LENGTH 8.
DATA:lv_len TYPE i VALUE 10000.
DATA:lt_table TYPE TABLE OF ztom_data.
DATA:lv_count_task TYPE i.
DO 10 TIMES.
lv_start = ( sy-index - 1 ) * lv_len.
lv_name = 'tax' && sy-index.
"异步调用function
CALL FUNCTION 'ZTOM_MODIFY'
STARTING NEW TASK lv_name
DESTINATION IN GROUP 'parallel_generators'
CALLING m_callback ON END OF TASK
EXPORTING
iv_name = lv_name
iv_start = lv_start
iv_len = lv_len
TABLES
t_data = lt_table
EXCEPTIONS
system_failure = 1
communication_failure = 2
resource_failure = 3.
IF sy-subrc = 0.
lv_count_task = lv_count_task + 1.
ELSE.
WRITE:/ 'some error'.
ENDIF.
WAIT UNTIL lv_count_suc >= lv_count_task.
LOOP AT lt_task INTO ls_task.
WRITE:/ ls_task-name,ls_task-lines.
ENDLOOP.
ENDDO.
ENDMETHOD.
"实现回调函数
METHOD m_callback.
DATA:lt_table TYPE TABLE OF ztom_data.
DATA:lv_line TYPE i.
RECEIVE RESULTS FROM FUNCTION 'ZTOM_MODIFY'
TABLES
t_data = lt_table.
lv_line = lines( lt_table ).
"记录task内表
CLEAR ls_task.
ls_task-name = p_task.
ls_task-lines = lv_line.
APPEND ls_task TO lt_task.
"成功回调计数
lv_count_suc = lv_count_suc + 1.
ENDMETHOD.
ENDCLASS.
方式2:使用Subroutine子函数
FORM f_update_data USING tax_id TYPE clike.
DATA:lt_table TYPE TABLE OF ztom_data.
DATA:lv_line TYPE i.
RECEIVE RESULTS FROM FUNCTION 'ZTOM_MODIFY'
TABLES
t_data = lt_table.
lv_line = lines( lt_table ).
lv_count_suc = lv_count_suc + 1.
ENDFORM.
"异步function
FORM f_test_parellel.
"RZ12查看
DATA:lv_start TYPE i.
DATA:lv_len TYPE i VALUE 10000.
DATA:lv_name TYPE C LENGTH 8.
DATA:lt_table TYPE TABLE OF ztom_data.
GET RUN TIME FIELD lv_time_begin.
DO 10 TIMES.
lv_start = ( sy-index - 1 ) * lv_len.
lv_name = 'tax' && sy-index.
"异步调用function
CALL FUNCTION 'ZTOM_MODIFY'
STARTING NEW TASK lv_name
DESTINATION IN GROUP 'parallel_generators'
PERFORMING f_update_data ON END OF TASK
EXPORTING
iv_name = lv_name
iv_start = lv_start
iv_len = lv_len
TABLES
t_data = lt_table.
IF sy-subrc = 0.
lv_count_parell = lv_count_parell + 1.
ELSE.
WRITE:/ 'some error'.
ENDIF.
ENDDO.
WAIT UNTIL lv_count_suc >= lv_count_parell.
GET RUN TIME FIELD lv_time_end.
lv_time = lv_time_end - lv_time_begin.
WRITE:/ lv_time.
ENDFORM.
ABAP内表行数最大差不多4千万笔数据,当数据库表数据大于这个条数时,对数据进行处理不能一次性读入内表,需要分批处理。
"大批量数据处理
FORM f_test_select_package.
DATA:lt_data TYPE TABLE OF ztom_data.
DATA:ls_data LIKE LINE OF lt_data.
DATA:lv_c1 TYPE cursor.
"1.使用select package
SELECT * INTO TABLE lt_data
PACKAGE SIZE 100
FROM ztom_data.
"中间处理逻辑
"因为内表容量限制,不能一次性读入内表处理,将大量数据分100次处理
ENDSELECT.
"2.使用open cursor
OPEN CURSOR lv_c1 FOR
SELECT * FROM ztom_data.
DO.
"每次处理1000条数据
FETCH NEXT CURSOR lv_c1 INTO TABLE lt_data PACKAGE SIZE 1000.
IF sy-subrc <> 0.
EXIT.
ENDIF.
LOOP AT lt_data INTO ls_data.
"处理读出来的数据
ENDLOOP.
ENDDO.
ENDFORM.