原文出自 江正军 技术博客,博客链接:www.cnblogs.com/jiangzhengjun
RFC
RFM限制
ABAP调用RFM
远程目标系统维护SM59
Connection type
Technical Settings
Logon/Security
Special Options
RFC不同的调用模式
同步调用RFC
同步远程对话处理
异步调用RFC(任务方式)
异步RFC调用
参数限制
接收返回结果
等待多个异步调用的返回结果
异步远程对话处理
并行RFC(负载均衡)
并行处理的前提条件
并行处理(相当于多线程)示例
Transactional RFC(事务性RFC方式的RFM调用)
1、调用参数
2、事务ID(TID)
3、设定作业开始时间
4、多LUW处理
5、出错处理
5、检查事务性RFC调用状态
通过程序
联机确定
队列RFC方式的RFM调用
本地RFM调用和回调
在本地调用远程功能
远程回调功能
异常处理
总结
实用RFC函数
动态访问表数据RFC_READ_TABLE
RFC
可以在SAP系统之间、SAP系统与非SAP系统之间进行远程调用,且调用可以是双向的(SAP系统可以调用非SAP系统、非SAP系统也可以调用SAP系统——如Java通过Jco连接器来访问SAP):
RFM限制
RFM:支持远程调用的功能模块。即SAP系统中的函数可以被其他SAP或非SAP系统调用
在SAP中,RFM的创建方式与普通功能模块类似,只是编写功能模块时,需要在Attributes选项卡中,将Processiong Type选项设定为Remote-Enabled Module。除了选中Remote-Enabled Module外,RFM还有如下要求:
参数声明:普通的FM定义形参时,并不一定要为参数指明所参照的类型(即可以不指类型,为通用类型),具体类型可在运行时根据实参类型确定,但RFM不能在运行时确定参数类型,因而必须在参数定义时必须指定参数的类型。此外,RFM中的参数必须指定为值传递(参数设定中的Pass Value选项)。(注:Table类型参数没有PassValue可选择,系统会默认隐式进行值传递)
参数格式转换:对于字符类型参数,传递过来的实参与RFM形参数定义的长度并不需要完全一致。如果传递进来的参数较短,RFC将在后面补充空格。但是调用方实参的定义长度不应大于被调用方形式的定义长度
异常处理:基于ABAP类异常是不能从RFM中抛回给调用系统的,因此避免使用。但可以通过老式的异常处理方式RAISE语句来抛出。此外,RFC接口还定义了两种预设的系统异常类型:
l SYSTEM_FAILURE,该异常报告远程系统中的所有失败和系统问题。
l COMMUNICATION_FAILUES,如果连接不能建立或通信中连接中断,将出现此异常。
在调用远程FRM时,调用方会可以使用这两种异常,因此不必在被调用者实现的程序代码中进行显示抛出。但在调用RFC功能模块时,必须进行捕获(其他不可预知的异常也要一并使用Others选项来捕获),否则出现异常时会使系统Dump掉。
ABAP调用RFM
DESTINATION附加项后面接的是远程目标名称,该目标在事务SM59中设定,其中包含连接和登录远程系统所需的全部参数信息。如果调用的就是本机的RFC目标,则DESTINATION可以使用<主机名>_<系统标识>_<实例编号>来指定(就是指下图中的Server Names),可以通过SM51查看当前SAP系统中活动的应用服务器:
DATA: gt_protocol TYPE btcxpm OCCURS 0 WITH HEADER LINE,
l_reason TYPE string.
CALL FUNCTION ‘SXPG_COMMAND_EXECUTE‘
DESTINATION ‘SAPECC6_ECC_00‘
EXPORTING
commandname = ‘ZDIR‘"宽屏显示服务器上D:盘目录的内容
additional_parameters = ‘d:\ /w‘"额外参数
* OPERATINGSYSTEM = SY-OPSYS
* TARGETSYSTEM = SY-HOST
* DESTINATION =
* STDOUT = ‘X‘
* STDERR = ‘X‘
* TERMINATIONWAIT = ‘X‘
* TRACE =
TABLES
exec_protocol = gt_protocol
EXCEPTIONS
no_permission = 1
command_not_found = 2
parameters_too_long = 3
security_risk = 4
wrong_check_call_interface = 5
program_start_error = 6
program_termination_error = 7
x_error = 8
parameter_expected = 9
too_many_parameters = 10
illegal_command = 11
wrong_asynchronous_parameters = 12
cant_enq_tbtco_entry = 13
jobcount_generation_error = 14
OTHERS = 15.
IF sy-subrc = 0.
LOOP AT gt_protocol.
WRITE: / gt_protocol.
ENDLOOP.
ENDIF.
程序说明:
SXPG_COMMAND_EXECUTE为SAP系统提供的标准预定义RFM,用来执行服务器上的操作系统命令。
本例中的DESTINATION 参数指定的是服务器名,并没有通过SM59进行定义,因为远程目标是同一SAP系统中的其他应用服务器,因此可以直接指定。如果远程目标是其他SAP系统,则必须在SM59中进行定义。
程序所执行的命令ZDIR是帖SM69中设定的,其命令的含义时,先运行操作系统的CMD命令,才紧接着执行DIR命令,并且在程序指定额外的参数,如显示指定的D:盘,并且以宽屏试 /w 显示。
远程目标系统维护SM59
上节中调用RFM示例中,直接指定了当前SAP系统内部的应用服务器作为远程目标。标准的作法是,先在RFC客户端(SAP主调方)系统中定义作为远程目标的RFC服务器,然后在ABAP调用时指定该远程系统,此时的远程系统可以是系统内部的应用服务器、其他SAP系统、及非SAP系统等。
这些配置信息都保存在RFCDES表中。除去SM59中定义的远程目标之外,SAP还提供两个预定义的目标,可以直接在CALL FUNCTION语句的DESTINATION附加项中使用。具体包括:
l 目标NONE:指定该远程目标意味着将运行当前程序的应用服务器作为目标系统,但是调用过程将通过RFC接口实现,并拥有自己的RFC上下文。该目标可以应用于任意调用类型。
l 目标BACK:用于被远程调用的RFM程序内部的CALL FUNCTION语句中的目标指定,通过已建立的RFC连接反过来调用该函数的主调者系统中的其他功能模块(即主调程序—>远程系统中的RFM—>又回调主调程序所在系统中的其他函数)
l 目标SPACE: DESTINATION选项将会被忽略,被调功能函数将作为普通函数在本机调用
Connection type
类型2(R/2连接),只需给出主机名,所有通信信息都已在存储在SAP网关的sideinfo表中,如果需要,也可以指定登录信息。
类型3(ABAP连接或称R/3连接),创建时必须给出主机名和通信服务。如果需要,也可以指定登录信息。还可以选择负载平衡选项。
类型I(内部连接),与当前系统连接到同一数据库的ABAP系统。这种类型的条目都是预定义的且无法修改。条目名称与事务SM51中所显示的应用服务器名相同。
类型L(逻辑目标),该条目不指定连接,而是参照物理目标生成。也可以参照其他逻辑目标生成。这类条目通常除包含所参照的条目中的信息外,还添加额外信息。一般情况下,所参照的条目会给出主机信息,类型L的条目本身给出登录数据。(通常工作流系统定制过程中需配置的RFC目标即为该类型的逻辑目标)
类型X,指定安装了特殊ABAP设备驱动程序的系统。在创建类型X条目时,必须给出ABAP设备驱动程序名。
类型S,定义通过SNA或APPC启动的外部程序连接。
类型M,定义通过CMC(即协议X.400)到ABAP系统中异步RFC连接。
类型T,定义通过TCP/IP并使用RFC库或SAP连接器的外部程序连接。该类型分为启动和注册两种连接模式。如果设为启动模式,必须指定要启动的主机名和程序路径名;如果设为注册模式,则需要指定一个RFC服务器程序。
类型G,定义外部系统到本地的HTTP连接
类型H,定义ABAP系统到本地的HTTP连接
Technical Settings
在Technical Settings(技术设定)选项卡,可以选择负载平衡选项,如果负载平衡选项选择YES后,则是还要指定下列内容:
l Target System(目标系统名称),即SM51中服务器名称中间的大写字母部分。
l Message server(目标系统的消息服务器),在目标系统的SAP中使用RZ03,应用服务器列表的Service栏中有“M”字符的条目即为消息服务器。
l Group(服务器组),在目标系统的SAP中使用SMLG,可查看服务器组。
否则,则需要指定下列内容:
l Target host(目标系统的主机名或IP地址),即事务SM51中的Host name字段,也可直接使用IP地址。
l System number(目标系统的系统编号),即事务SM51中服务器名称中最后两们数字编号。
此外,该选项卡中还可以指定网关信息,对于其他类型连接,还可以指定该系统所用的通信服务,如TCP、SNA等。
Logon/Security
该选项卡中,可以设定登录语言、集团、用于远程登录的用户名以及密码。在该选项卡中,还可以设定与系统安全相关的选项:
l Trusted system ,对于类型3的远程目标,可以将服务器系统设定为可信任系统(SMT2设定可信任系统),则RFC用户无需再设定登录密码。
l SNC(secure network communication),对于类型3或T的远程目标,如果服务器为支持SNC的安全系统,可以通过Destinations->SNC菜单启动相关的安全选项。
Special Options
该选项卡中,可以设定系统跟踪(Trace)、缓慢RFC连接(Slow RFC Connection)选项、目标系统的字符宽度以及和Unicode连接时特定的字符转换相关选项。
RFC不同的调用模式
CALL FUNCTION中的DESTINATION可以是文字或变量,其值为SAP系统中已知的远程目标系统,除去SM59中手工定义的目标外,如果远程系统就是当前系统的SAP应用服务器,也可以直接指定应用服务器名称,即SM59中的I类型目标。
注意:SM59中定义的RFC目标是区分大小写的,DESTINATION附加项中目标变量的值必须与其完全一致,包括大小写。但如果直接指定SAP应用服务器名称,则无此限制
同步调用RFC
远程调用时,通信双方的系统必须均可用,主调程序等待远程功能处理结束并返回结果:
CALL FUNCTION func DESTINATION dest
parameter_list.
对于表类型参数,在本地普通功能调用中默认就是为引用传递(实质为传递字段符号),但RFC中不支持引用传递机制,所以也将默认进行隐式的值传递调用,另外,只会传递表本身,不会传递表头。
对于内表类型的参数,只有扁平结构可以被传输,但EXPORTING、IMPORTING和CHANGING可以用于传输纵深类型及STRING等类型的数据。
同步远程对话处理
对于同步RFC和异步RFC,可以存在对话过程,如 CALL SCREEN、CALL TRANSACTION或列表处理等,但要注意的是,以后台模式调用有对话程序的RFM,则将导致程序中断,会引发系统异常 SYSTEM_FAILURE。
如果远程RFM处理时出现交互对话过程,将在当前调用程序的会话中先进行远程对话处理,处理结束之后再继续调用程序:
异步调用RFC(任务方式)
主调程序的执行并不依赖于RFC服务器系统的可用性,被调用的远程功能启动后,调用程序继续运行,远程功能和调用程序处理相互分离,远程功能的结果可以稍后接收:
CALL FUNCTION func STARTING NEW TASK task
[DESTINATION {dest|{IN GROUP {group|DEFAULT}}}]
[{PERFORMING subr}|{CALLING meth} ON END OF TASK]
parameter_list.
STARTING NEW TASK表示异步调用模式,task为任务的名称,可以任意,通常对于不同的异步调用,应该指定不同的任务名
在异步RFC调用中,DESTINATION并不是必须的,即远程系统的指定并不是实现异步RFC调用过程的前提条件(但函数一定要是RFC函数才能采用异步调用),只要出现STARTING NEW TASK附加项,系统就将以异步RFC进行功能调用
异步RFC调用
参数限制
异步RFC调用过程只能使用 TABLES、EXPORTING(对应功能模块设定中的Import参数)和EXCEPIONS参数。调用程序并不等待该模块返回结果,因而不能指定IMPORTING参数(其返回结果需要在回调子程序中进行处理)。而且,调用的同时只能接收系统标准异常COMMUNICATION_FAILURE和SYSTEM_FAILURE,对于功能模块中抛出的其他特定异常则不能直接接收,也需要在回调子程序中处理。
接收返回结果
如果需要在异步RFC模式下接收远程模块的返回结果或特定异常,可以通过调用语句中的附加项PERFORMING return_form ON END OF TASK实现:
CALL FUNCTION rfm_name
STARTING NEW TASK taskname
PERFORMING return_form ON END OF TASK
...
其中指定的子程序必须存在于调用程序中,并包含RECEIVE语句:
FORM return_form USING taskname.
...
RECEIVE RESULTS FROM FUNCTION rfm_name
...
ENDFORM.
当被调用RFM功能模块执行结束后,系统将自动执行回调子程序return_form,return_form子程序必须包含一个任意的名称、类型的形式参数,以接收对应异步RFC调用的任务名称。
注:回调子程序return_form中不能包含任何使当前程序执行中断的语句,例如:CALL SCREEN、SUBMIT、COMMIT WORK、WAIT、RFC调用及W或I类型的消息等,否则是不能成功将结果输出到屏幕上,此外,子程序中的WRITE语句也将失效。
DATA: msg_text(128).
DATA: gt_protocol TYPE btcxpm OCCURS 0 WITH HEADER LINE.
CALL FUNCTION ‘SXPG_COMMAND_EXECUTE‘
* DESTINATION ‘SAPECC6_ECC_00‘
STARTING NEW TASK ‘B1‘
PERFORMING return_frm ON END OF TASK
EXPORTING
commandname = ‘ZDIR‘
additional_parameters = ‘d:\ /w‘
EXCEPTIONS
communication_failure = 1 MESSAGE msg_text
system_failure = 2 MESSAGE msg_text.
IF sy-subrc = 0.
WRITE: ‘Wait for reply.‘.
ELSE.
WRITE msg_text.
ENDIF.
AT USER-COMMAND.
IF sy-ucomm = ‘OK‘."此处的FunctionCode为 return_frm 函数所触发
IF msg_text = space.
LOOP AT gt_protocol.
WRITE: / gt_protocol-message.
ENDLOOP.
ELSE.
WRITE : ‘--‘ , msg_text.
ENDIF.
ENDIF.
FORM return_frm USING taskname.
RECEIVE RESULTS FROM FUNCTION ‘SXPG_COMMAND_EXECUTE‘
TABLES
exec_protocol = gt_protocol
EXCEPTIONS
communication_failure = 1 message msg_text
system_failure = 2 message msg_text.
" WAIT UP TO 1 SECONDS."在接收Form中不能出现中断语句,否则抛异常
SET USER-COMMAND ‘OK‘."接收到异步返回结果后,自动触发一个列表事件,如果有输出,将会显示下一级别的List屏幕
ENDFORM.
要想将结果输出到屏幕上,这里一定要在 AT USER-COMMAND事件中输出
等待多个异步调用的返回结果
语句WAIT UNTIL用于异步RFC调用中等待结果的返回,该项必须与PERFORMING附加项配合使用,否则没有意义,也无任何效果:
WAIT UNTIL log_exp [UP TO sec SECONDS].
注:WAIT UP TO 1 SECONDS.不需要与PERFORMING选项配合使用,也就是说可以使用在普通的ABAP程序中,用来暂停当前会话线程
该语句执行时,log_exp中的条件将被检查(或者到达指定的等待时间sec),仅当条件满足时,主调程序继续执行;否则程序将挂起,并等待异步RFC调用的返回结果。
使用WAIT UNTIL语句等待多个RFM返回结果的异步RFC调用示例代码段可参考这里
异步远程对话处理
异步RFC调用过程也支持远程对话处理,在异步RFC调用时,系统总是打开新的工作过程,因而如果被调用功能模块中包含对话过程(即屏幕处理),则在该功能模块执行时,在主调系统中将出现新的外部会话容器,用户可以和远程系统交互对话,并允许在调用程序对话和被调用对话之间来回
并行RFC(负载均衡)
并行RFC调用实际上是异步RFC调用的应用之一
异步RFC调用只适用于多个SAP ABAP系统间的并行处理,不支持SAP系统和其他系统之间
通过事务SM59中的菜单项 RFC->RFC groups,可以将SAP系统的应用服务器分配成不同的RFC分组。异步RFM调用时,可以通过DESTINATION子句中的IN GROUP附加项指定一个已定义的RFC分组,系统将选择组内负载最小的应用服务器来执行该模式,如果不指定,还可以使用关键字 DEFAULT,系统将从全部可用的应用服务器中选择一个来处理
并行处理的前提条件
独立的LUW:并行处理不适合需顺序进行的数据处理,并行的数据处理任务必须逻辑上独立于其他任务,各个数据处理过程不能具有依赖关系
被调用的功能模块程序中不能再包含使用目标BACK的远程功能调用(即不能再进行回调)
调用程序不能在异步调用之后生成新的内部会话,即不能在CALL FUNCTION STARTING NEW TASK语句后使用SUBMIT或CALL TRANSACTION语句
不能通过CALL FUNCTION STARTING NEW TASK DESTINATION IN GROUP语句启动外部程序
并行处理(相当于多线程)示例
TYPES: BEGIN OF task_type,
name TYPE string,
dest TYPE string,
END OF task_type.
DATA:snd_jobs TYPE i,
rcv_jobs TYPE i,
exc_flag TYPE i,
info TYPE rfcsi,
mess(80),
indx(4),
name(8),
task_list TYPE STANDARD TABLE OF task_type,
task_wa TYPE task_type.
DO 9 TIMES.
indx = sy-index.
CONCATENATE ‘Task‘ indx INTO name.
CALL FUNCTION ‘RFC_SYSTEM_INFO‘
STARTING NEW TASK name
DESTINATION IN GROUP DEFAULT
PERFORMING rfc_info ON END OF TASK
EXCEPTIONS
system_failure = 1 MESSAGE mess
communication_failure = 2 MESSAGE mess
resource_failure = 3 .
CASE sy-subrc.
WHEN 1 OR 2.
MESSAGE mess TYPE ‘I‘.
WHEN 3.
MESSAGE ‘Resource failure ‘ TYPE ‘I‘.
ENDCASE.
ENDDO.
WAIT UNTIL rcv_jobs = 9 UP TO 10 SECONDS.
LOOP AT task_list INTO task_wa.
WRITE: / task_wa-name,task_wa-dest.
ENDLOOP.
FORM rfc_info USING name.
task_wa-name = name.
rcv_jobs = rcv_jobs + 1.
RECEIVE RESULTS FROM FUNCTION ‘RFC_SYSTEM_INFO‘
IMPORTING
rfcsi_export = info
EXCEPTIONS
system_failure = 1 MESSAGE mess
communication_failure = 2 MESSAGE mess.
IF sy-subrc = 0.
task_wa-dest = info-rfcdest.
ELSE.
task_wa-dest = mess.
ENDIF.
APPEND task_wa TO task_list.
ENDFORM.
Transactional RFC(事务性RFC方式的RFM调用)
事务性RFC,广义上也属于异步,主调程序不接收结果而继续运行,但并不立即启动远程功能。相关联的RFC可绑定到一个事务单元上LUW,等待主调程序中的COMMIT WORK语句时,一次性执行多个远程函数调用。此种方式的调用解决了调用多个远程RFM时事务问题
CALL FUNCTION func IN BACKGROUND TASK
[AS SEPARATE UNIT]
[DESTINATION dest]
parameter_list.
CALL FUNCTION func IN BACKGROUND UNIT
parameter_list.
上文中的同步和异步调用RFC时,每一个RFC调用都在远程系统中构成一个独立的LUW,即在调用多个RFM时,不会放到一个事务里:
通常情况下,普通的功能模块的调用和主程序位于相同的LUW 中,即在同一事务中,所以不会出现事务性问题;但同步RFC和异步RFC调用中的每一个功能模块都拥有自己的LUW,即在每一次远程调用结束时,当前程序都将进行内存区的释放,因此将触发隐式的数据库提交,这样,之前的所有数据库更新将不能回滚。对于事务性RFC,则将相关机制将多个远程调用操作绑定到同一个LUW,实现整体提交或回滚,调用RFM时主调程序并不会立即发送调用远程目标上的RFM,而是等到COMMIT WORK才开始去真正去执行RFM:
选项IN BACKGROUND TASK/UNIT指明该调用为事务性RFC,后者为ABAP7.0版之后针对对象引用的新格式,其中oref必须引用一个接口IF_BGRFC_UNIT实现类的对象。在相邻两个COMMIT WORK语句之间出现的所有相同目标的异步调用都属于同一个LUW。
与异步RFC调用类似,事务性RFC调用也不需要等待每个RFM执行完,主调程序就可以立即继续进行;但不同之外在于事务性RFC调用时,不要求远程RFC服务器可用;事务性RFC不能从调用模块RFM中接收返回结果,且不允许调用者与远程系统的交互性对话及调试
1、调用参数
事务性RFC调用不能直接接收或通过RECEIVE RESULTS FROM FUNCTION语句接收FRM的返回结果。因此,RFM功能模块的接口不应指定任何Export类型参数,否则该功能就不能通过事务性机制调用。此外,事务性的功能模块RFM中不适合进行回调(此时远程目标参数DESTINATION为BACK,即在远程RFM程序中返过来调用主调程序所在系统中的其他函数模块),因为在将回调返回原始系统时,调用程序上下文不一定仍然存在。
2、事务ID(TID)
每个事务性RFC调用均通过一个独特的事务ID存储于本地数据表ARFCSSTATE和ARFCSDATA中,其中ARFCSSTATE记录LUW的执行状态,ARFCSDATA则包含事务性RFC调用的输入数据。当主调程序执行到COMMIT WORK语句时,将为远程LUW计划一个立即或延迟的后台作业,并将远程调用转发给目标系统进行执行。在作业执行过程中,从事务性RFC表中读取相关数据,与相应的事务性RFC进行通信,如果远程的LUW被成功执行,则相应的条目在表中将被删除。因此,如果LUW运行成功,则无法重新执行,因而保证了仅仅执行一次。
注:如果在主调程序COMMIT WORK 语句触发时,需要执行本地数据表更新操作,则事务性RFC调用则会放在本地更新操作成功完成之后才开始执行远程的
3、设定作业开始时间
默认情况下,在运行到COMMIT WORK 语句后指定的目标系统中将立即执行LUW,但如果希望在指定的时间启动LUW,可以通过函数START_OF_BACKGROUNDTASK设置作业开始时间,注:必须在CALL…IN BACKGROUND TASK语句之后或COMMIT WORK语句之前调用该函数
4、多LUW处理
在事务性RFC调用过程中,如果在COMMIT WORK语句之前出现的事务性RFC调用分别针对多个不同的目标,则系统将根据其目标分组为多个不同的LUW,相同目标的调用组合到同一个LUW中,在COMMIT WORK语句执行时,处理所有的LUW
如果不想将相同目标的事务性RFC调用组合到一个LUW,可以调用AS SEPARATE UNIT附加选项实现
5、出错处理
如果有错误发生,事务性RFC调用将启动重试机制或者回滚,具体处理:
l 通过COMMIT WORK执行远程调用时,如果不能建立到目标系统的连接,将在ARFCSSTATE表中记录当前状态,系统将通过系统报表RSARFCSE根据当前的TID(事务ID)重新计划后台作用,进行下一次调用。这可以通过事务RFC调用选项为特定目标系统设定尝试次数和时间间隔,默认为时间间隔为15分钟,尝试30次(这些默认值可以通过 SAP右侧初始菜单 TOOLS->ADMINISTRATION->ADMINISTRATION->NETWORK-RFC DESTINATIONS来修改)。如果经过最大尝试次数后系统仍无法连接,系统将停止调用报表RSARFCSE,并将ARFCSDATA中状态更新为CPICERR。特定时间后(默认8天)将表中的相应条目删除(但仍然可通过事务SM59手工启动)
l 如果在RFM的执行过程出错,如A类型的消息或才RAISE语句抛出异常,则ARFCSSTATE表中将记录出错状态,整个RFC中的操作将取消,出错之后不再将后台作业重启,ARFCSSTATE表中的信息也不会被删除。在主调用系统中可以通过事务SM58查看该错误,并在远程系统中修改错误之后,通过SM58重新启动出错的RFM
5、检查事务性RFC调用状态
可通过以下两种方式来检查TID(事务ID)的状态
通过程序
首先,TID可以通过调用功能模块 ID_OF_BACKGROUNDTASK,在CALL…IN BACKGROUND TASK与COMMIT WORK 之间调用一获取LUW的TID。获得LUW 的TID之后,就可以继续使用功能函数STATUS_OF_BACKGROUNDTASK确定事务性RFC的状态了:
联机确定
通过SM58显示维护事务性RFC的LUW状态
相相关事务码:SM59、SM58
队列RFC方式的RFM调用
队列RFC是事务性RFC功能上的进一步的扩展。在事务性RFC中,如果COMMIT WORK语句提交多个LUW,那么各LUW之间相互独立,其处理顺序并不与创建顺序相同,这些LUW执行次序是无法确定的。如果要保证这种顺序,需要使用队列RFC创建LUW序列,队列RFC是事务性RFC的增强版本,可以用于SAP与SAP及SAP与非SAP之间的连接。
上图中(1)是普通事务性RFC调用过程,各功能模块RFM是相互独立的,执行顺序不确定;图中(2)是含出站队列的RFC,在发送前,先按预期的处理顺序入队,再由主调系统发送处理,此种解决了各独立的RFM在处理上的先后问题;图中(3)是含入站队列及出站队列RFC,此种情况下与(2)不同的只是在被调系统中增加了队列,缓解了服务器压力,有效地利用双方系统的资源,避免了大量事务RFC调用而造成的服务器端阻塞,但其作用还是与(2)一样,解决了相互独立的RFM按顺序处理的问题
通过事务SMQS可以配置出站的队列RFC序列;通过事务SMQR,可以配置入站的队列RFC序列
在编程时,需要在普通事务性RFC调用之前使用功能模块TRFC_SET_QUEUE_NAME来指明后续的事务性RFC所要插入的出站队列;入站队列的指定则通过调用功能模块TRFC_SET_QIN_PROPERTIES来完成。
本地RFM调用和回调
通过DESTNATION选项支持的两个特殊目标NONE与BACK,可以进行RFM的本地远程调用和回调
在本地调用远程功能
有时需要在本地系统中调用远程功能模块,即调用当前系统内部的RFM,功能既能以远程调用方式运行,也能以非远程调用方式运行,这取决于CALL FUNCTION语句的格式。以远程方式进行的本地调用格式如下:
CALL FUNCTION rfm_name
DESTINATION ‘NONE‘
...
远程目标 NONE表示,远程功能与调用程序在相同系统中运行。作为远程调用,功能模块通过RFC接口被调用,在自己的内存区运行,有远程上下文,参数的处理过程与其他远程调用相同。
正常的本地调用(非远程调用)中,CALL FUNCTION 语句没有DESTINATION、STARTING NEW TASK或者IN BACKGROUND TASK/UNIT这三种附加项的任何之一出现,此时即使函数属性设置成了“可远程调用的”,函数模块也不在独立的内存中运行(与主调程序在同一会话内存中执行),本质上与普通的功能模块函数相同
远程回调功能
在服务器(RFM所在机器、被调用者,而非主调者)上执行远程功能时,该服务器(被调者)也可以调用客户(主调者)中随调用程序载入内存的功能模块,这个过程称之为回调
通过特殊的目标名BACK可触发回调机制:
系统在回调过程中将使用与服务器接收第一个远程调用时相同的RFC接连。建立RFC连接之后,在显式关闭或调用程序终止之前,该连接将一直保持。在回调过程中,建立新的连接之前,系统将尝试使用现有RFC进行连接。
如下图,服务器端的远程功能B可以调用客户端的原始调用程序中的功能模块C,甚至可以是程序本身A(注意:只有在同步调用时,才可以在服务器被调用功能模块中回调客户端功能)
异常处理
系统将自动处理标准异常COMMUNICATION_FAILURE和SYSTEM_FAILURE。如果在系统中没有正确维护远程目标,或到远程系统的连接不能建立,系统将触发COMMUNICATION_FAILURE异常;如果远程连接成功,但所指定的远程功能不存在于目标系统中,系统将触发SYSTEM_FAILURE异常,必须在功能模块调用部分的代码中显式捕获上述异常,此外,还应在远程功能中定义其他可能抛出的异常。
DATA: message_txt(128).
CALL FUNCTION ‘ZRFC_USER_READ‘
DESTINATION ‘GS4CLNT100‘
...
EXCEPTIONS
communication_failure = 1 MESSAGE message_txt
system_failure = 2 MESSAGE message_txt.
如果上述程序发生异常,并不会引起Short Dump中断,异常信息将被存储到MESSAGE附加项指定的变量message_txt中(注:其他异常不能使用 MESSAGE选项)
总结
l 同步RFM调用需要等待RFM返回结果之后,主调程序才能继续执行,而异步RFM调用则不需要等待返回结果;但需要通过RECEIVE语句在回调子程序中来接收结果;事务性RFM的调用则不能接收RFM返回值
l 对于同步、异步RFM,服务器系统必须在调用时可用,而事务性RFM调用则无些限制
l 同步RFM调用和异步RFM调用过程中,允许用户与远程系统进行交互对话(其方式有差异),事务性RFM调用则不支持
l 同步和异步RFM调用时,参数值将直接传输至远程功能模块函数,但在事务性RFM中,参数将暂时存储于数据库中,待执行时才传入给远程函数
l 同步RFC和事务性RFC可以在SAP与非SAP系统之间进行调用,而对于异步RFC,只适用于SAP系统内部或之间调用
实用RFC函数
动态访问表数据RFC_READ_TABLE
动态输入任何表名,及查询条件,即可查询数据
DELIMITER参数:由于查询出来的数据是将查询出来的所有字段拼接在一起一个字符串,之间用什么分隔可以在这里指定,比如“|”竖线,如果不指定,则需要按照字段的长度来自己划分
如果在查询时不传入FIELDS参数值,则返回输入表的表结构信息:每个字段起始索引(按SE11中字段定义的选择顺序来算)、长度、类型:
==========================================================
输入查询条件:
还需要在TABLE参数FIELDNAME 中定义数据返回的字段格式:
查询结果: