RFC Programming in ABAP

转载自:http://blog.csdn.net/cs0123456789/article/details/7034893

RFC Programming in ABAP
目录
<1> RFC 基础
<2> RFC 界面
<3> SAP系统中的RFC
<4> 需要的技术
<5> 在ABAP中调用RFC
<6> 介绍
<7> 在远程调用时,参数处理
<8> 本地调用RFC
<9> RFC调用的返回信息
<10>在RFC中使用事务
    tRFCs
<11>qRFC,传递队列
    概览overview
    programming serialization
    using
    事务队列和队列设置
    工具
<12>RFC异步调用
    异步调用RFC的要求
    从一个异步调用RFC中接受结果
    保持远程上下文
    平行处理异步调用RFC
<13>检测RFC权限
<14>定义RFC异常
<15>在abap中写RFC
<16>RFC处理步骤
<17>程序方针
<18>调试RFC模块
<19>维护远程目标
<20>显示,维护,和测试远程目标
<21>输入目标参数
<22>目标类型
<23>维护目标组
<24>维护R/3系统之间的信赖关系

 

<1>RFC Basis,基础
   这一节给出了一个纲要,来浏览在一个sap系统中的RFC,纲要如下:
   RFC接口是如何工作的
   RFC提供的功能
   技术需求以及所支持的所有平台

   (1) RFC 接口 
       RFC是对一个函数模块的调用,但是调用者的系统与被调函数所在的系统是不一样的。
       RFC也可以在系统内被调用,但是通常调用和被调用是在不同的系统中的。
       
       在sap系统中,远程调用的能力是有RFC接口系统提供的。 RFC允许在两个sap系统(R/3或者R/2)之间进行调用。或者
       是在一个sap系统和非sap系统之间调用。
       
       RFC由以下的接口组成
       . 在abap程序的调用接口
         任何一个abap程序都可以调用一个远程调用函数,使用语句:CALL  FUNCTION ....DESTINATION.
         这个DESTINATION参数告诉SAP系统,被调函数运行的系统不同于访问者的系统。
         RFC与远程系统的通讯作为CALL FUNCTION语句的一部分。
       
         运行在一个sap系统上的RFC函数,必须是真实存在的函数模块,并且必须在sap系统中显示为"remote".

         当访问和被访问的都是abap程序,那么RFC接口提供两者到通讯中。访问者可能是任何abap程序,但是
         被调用的程序必须是一个RFC函数。
         主题:在abap程序中调用RFC函数, 提供了详细的信息。
         主题:在abap程序中写RFC函数, 提供了写你想要调用的远程函数的信息。

       . 在非sap程序中调用接口
         当访问者或者被访问者是一个非sap程序,那么那个非sap程序就被规划为运行另一个程序,在RFC通讯中。
         为了帮助运行RFC程序,在一个非sap系统中,sap提供了
         -- 外部接口(Ext)
           基于RFC和基于GUI的接口可以被外部程序使用,来调用在sap R/2或者 R/3系统中的函数模块,并且在
           R/2 R/3系统中运行。
           在R/2 或者 R/3系统中,abap程序,可以使用由外部程序提供的函数,通过这些接口。

           假如你想要看在一个程序例子中的相关情节信息,请看相对应的单元,在教程:通讯接口(Ext).

       <2>RFC in sap systems
          在任何一个R/3系统中,CALL FUNCTION 是abap语言中的一部分(在R/2 Release 5.0 以上开始).它被用来执行一个函数。
          RFC 是一个CALL  FUNCTION 的分类上的扩展,Existing function module 可以在R/2或者R/3系统中,通过一个RFC调用,
          来执行。这个过程通过添加一个DESTINATION 子句到CALL FUNCTION语句,来实现。
          例子:
             SAP System A                              SAP System B                   External Client Program
             ABAP Program                        ABAP Function Module               Routine
             ...                                                                   
             CALL FUNCTION 'ABC'                 FUNCTION ABC.                      Rfcopen(...)
                DESTINATION 'DEST'                  ...                             RfcCallReceive('ABC')
             EXPORTING  f1 = a1                  ENDFUNCTION.                       ...
             IMPORTING  f2 = a2                                                     RfcClose(...)
             CHANGING   f3 = a3
             TABLES     t1 = tab                 External Server Program
             EXCEPTIONS                          Routine
               COMMUNICATION_FAILURE = 1         main()
               system_failure        = 2         [
             ...                                    RfcAccept(..)
                                                    RfcInstallFunction{'ABC',abc ...}
                                                    RfcDispathc(...)
                                                    ...
                                                    RfcClose(...)
                                                  ]
                                                    RfcGetData(...)
                                                    RfcSendData(...)
              
             这个目标参数destination 呈现一个入口,在RFCDES表中(通过sm59可以定义destination).这个入口包含了所有必要的字段,这些字段
             用来连接和登陆到目标系统中。
             
             RFC 可以在R/2 R/3系统之间使用。 在一个IBM环境中的R/2系统,RFC通常为CICS作为一个DC系统,在版本5.0D以上。
             在IMS环境中,RFC在IMS 4.1之前,是不可用的。 完全支持LU6.2协议(通过MVS/APPC).
             在 OS/2,Windows,windows NT 和所有基于R/3的unix平台上的RFC API,使应用RFC功能,在SAP系统(R/3从版本2.1,R/2从版本5.0D以上)
             和C程序之间成为可能。对于访问者,无论远程调用函数是由SAP系统还是C程序提供都已不重要了。

             abaper可以非常自由的写自己的通讯程序。
             当你调用一个RFC函数,RFC接口关注于:
             . 转变所有的参数数据为远程系统所需要的形式。这里包含字符串转换,和任何依赖硬件专换要求(如,整数,浮点数)。
               所有的abap数据类型都被支持。
               注意: 对于字典结构,没有支持。
             . 调用通讯程序,需要告诉远程系统
             . 处理通讯程序错误,并通告访问者。
             
             RFC接口对于abaper是不可见的。 处理远程程序调用是建立在CALL FUNCTION语句中的。处理被调用是自动的(以一个RFC stub 形式),对于每一个显示为remote
             的函数来说。这个stub 作为调用RFC的程序和RFC函数的接口。
             
             RFC client 和 RFC server 之间的区别。RFC client 是召唤RFC来执行函数的,而被执行的函数由RFC server提供。
             以下将,被远程执行的函数叫RFC functions, 将通过RFC API提供函数的叫RFC calls.
            
             所有RFC functions 都是可用的,在一个远程RFC服务系统中。这就意味着在执行完第一个RFC function,那么完成的上下文信息(所有的在RFC服务程序中
             定义的全局变量或者在一个函数模块的主程序中) 可以被用来接下来的RFC functions 中。RFC连接仅在以下情况关闭:
             . 当上下文信息在程序中中断掉,或者 在外部程序中通过RfcAbort或者RfcClose明确的关闭。

             在一个R/3系统,其它的R/3系统可以被定义为信赖的系统。那么信赖的系统可以进入到被访问的系统,而不需要提供密码。


       <3> 所需要的技术
           外部系统
           . OS/2                    TCP/IP  
           . Windows 3.1/ 3.11       所有TCP/IP 产品,支持socket 接口
           . Window NT/95            微软标准
           . UNIX 平台               行业标准
           
          不同的平台需要包含的库和文件。
          不详述.....
       
       <4> 在abap中调用远程函数.
           这一节包含以下主题:
           介绍
           参数处理
           本地调用
           有返回
           使用事务
           使用异步
           检测权限
           预先定义异常
           
         (1) 介绍
             与普通的函数相比, 你要包含额外的destination子句,来定义这个函数是在那里运行的。(调用来,不是在本地运行的,而是在目标服务器上运行的)
             CALL FUNCTION RemoteFunction
                  DESTINATION Dest
             .....
             
             字段Dest可以是一个字符,也可以是一个变量:它的值是一个逻辑目标(例如:hw1071_53),可以被本地的sap系统识别。Logical destinations 可以被定义
             到RFCDES表中(或者是TRFCD表,在R/2系统中), 可以通过sm59事务或者根据菜单路径: TOOLS , Administration, Adminstration network RFC destinations,
             来定义。你也可以通过执行Guide(IMG)进入到Logical destinations. Tools->Customizing->Enterprise img. ->Cross-application components -> ALE ->
             Communication -> Define RFC destination.

             RFC的概念: 例如,允许你进入一个R/2系统的函数模块,通过一个R/3系统的函数。假如你想要读客户记录从你的R/2系统的数据库中,那么在那个可以接受客户记               录的R/2系统环境中创建一个远程调用函数。从你的R/3系统中,调用这个函数。 使用RFC,并且列出到R/2系统的Logical destinations.
             R/3 系统: client
                CALL FUNCTION 'RFC_CUSTOMER_GET'
                  DESTINATION 'K50'
                  EXPORTING  KUNNR = custno
                  TABLES     CUSTOMER_T = ITAB
                  EXPORTING   kunnr = custno
                  TABLES      customer_t = ITAB
                  EXCEPTIONS  NO_RECORD_FOUND = 1.

             R/2 系统: Server
                  FUNCTION RFC_CUSTOMER_GET.
                      (Read customer record)
                  ENDFUNCTION.
         (2) 参数处理
             当你调用一个RFC,系统处理参数传递与调用本地函数进行参数传递,是有区别的。
             TABLES parameters
             实际的数据库表会被传递,而不是表头。假如一个表参数没有指定,那么一个空的表会在被调函数中使用。
             RFC使用一个得耳塔管理机制来缩短网络下载参数和结果数据。abap内表可以被用来作为RFC的参数。在一个本地函数调用时,一个参数内表
             通过指针来传递,并且没有新的本地拷贝副本被创建.RFC不支持指针机制。因此整个表不得不被传递,在RFC client和RFC server之间。
             当RFC server接收到表入口,它将创建一个本地的内表拷贝。然后仅delta信息被返回到了RFC client。这个信息不是一旦有表被操作就传递到
             RFC client的,然而,代替的是,当所有的delta信息都集中了,然后就一次性的传递到RFC client.

             当第一次一个表被传递,就给定了一个object-ID,并且别注册是"Virtual global table"在调用系统中(RFC client所在系统)。
             这个信息将一直被保留一直到函数返回。然而,假如多重call-backs产生,change-log将被传递回来,并且更新前面的本地拷贝,但是表本身仅
             需要拷贝一次(第一次).

         (3) Calling RFC locally
             有些时候,你想要调用一个远程函数(就是,一个显示为远程的函数)从一个相同的系统中。那么这个函数即可以以远程方式运行也可以以本地调用
             方式运行,这个决定于CALL FUNCTION语句。是否是以远程方式或者是本地方式,会影响到参数的处理方式(如上面所讲述)。
             两种选择:
              . CALL FUNCTION ...DESTINATION = 'NONE'
                这是一个远程调用,即使DESTINATION = 'NONE',但是这意味着远程函数将会运行在访问者相同的系统中。 因为是远程调用,那么函数运行在
                它自己的区域。
              . CALL FUNCTION ... [no DESTINATION userd]
                这就是本地调用了,即使这函数被显示为远程的。函数不会被运行在不同的区域,并且作为普通的函数调用。
                参数传递也以普通函数模块处理的方式。特别的是,假如一些EXPORING未指明,它就会异常中断。
                CALL FUNCTION 'RFC_CUSTOMER_GET'
                     EXPORTING  kunnr = custno
                     TABLES     customer_t = ITAB
                     EXCEPTIONS no_record_found = 01.

         (4) Calling Remote Functions BACK
             RFC client 和 RFC server 在RFC开始的时候就已经被决定了。 当一个函数正在被处理在RFC server上,那么这个 server可以在RFC client上调用一个函数。
             换句话说,RFC调用它的访问者(假如访问者自身是一个函数模块),或者任何一个装载访问者的函数模块。那么call-back 函数会运行在相同的
             程序上下文,作为原先的访问者。

             你可以追踪这个call-back 机制,通过使用特别的desitination 名称'BACK'.假如这个名称被指定到RFC调用的系统担当RFC server,那么系统将使用相同的
             RFC连接,这个连接在RFC server接收第一次调用的时候建立。一旦一个RFC连接被建立,它就可以一直维持直到它被明确的关闭或者调用函数被关闭。
             在一个call-back过程中,系统将一直试图使用已经存在的RFC 连接在创建一个新的连接之前。
             
             语法如下:
             CALL FUNCTION ... DESTINATION 'BACK'
               在这个程序中,在系统B中的远程函数B,调用远程函数 A在系统A中。
               System A                                      System B
            CALL FUNCTION 'B'  ---------------->  FUNCTION B.
            ^   DESTINATION 'B'                       .....
            .          .......  
            .       FUNCTION A. <-----------------------  CALL FUNCTION 'A'
            .                                               DESTINATION 'BACK'
            .         ....                                  .....
            .      ENDFUNCTION.   ----------returnA------>  .....
            .
            -----------------------return B------ENDFUNCTION.

            (A,B都是远程调用函数)
       
       (5)Using Transactional Remote Function Calls
          从版本3.0以后,数据可以在两个R/3系统中,可靠安全的进行访问,通过tRFC.
          这个类型的RFC是由异步transactional RFC重新命名来,因为异步RFC在R/3系统中有其它名字。
          被调函数模块被准确的执行一次在RFC server系统中。远程系统并不需要可用,当RFC client程序正在执行一个tRFC的时候。
          tRFC组件保存了被调RFC函数连同相关的在R/3数据库表中的数据,包含一个唯一的事务识别ID(TID).
          
          假如一个调用被传递,但是接收系统崩溃,那么这个调用仍然存在本地的队列中,直到later time.
          调用的对话程序,可以执行不需要等待远程调用是否成功。假如接收系统没有活动在某段时候内,那么调用将会被计划到队列。
          tRFCs 使用后缀在后台任务中。
          
          因为是异步调用,destination参数定义了一个程序上下文在远程系统中。结果,假如你重复调用了一个函数(或者一个其他的函数)在相同的destination中,
          那么被调函数的全局数据将会进入到相同的上下文信息中。
          
          系统记录远程调用请求在数据库表ARFCSSTATE和ARFCSDATA中,包含它所有的参数值。你可以显示这个日志文件使用事务SM58.当调用程序完成了工作,那么
          远程调用就进入到系统请求并进行执行。

          所有的tRFCs带有一个destination.这个destination,只在一个commit work中有效,而下一个destination,则归属于另一个LUW单元。对于更多的关于LUWS
          TIDS和检测tRFC状态的信息,请看Transactional integrity of tRFCs.

          tRFC 请求被传递,其参数数据以byte-stream 的形式传送,使用TCP/IP 或者X400.

          CALL FUNCTION ....
             IN BACKGROUND TASK
             DESTINATION
               EXPORTING ....
               TABLES    ....
          COMMIT WORK.
          其中,函数名进入 ARFCSSTATE, 参数数据进入ARFSCDATE.

          举个例子,你可以使用tRFCs,作为特殊的更新程序。
          一些复杂的对话,需要几个关联的数据库表被更新,在同一个事务下的不同阶段。假如更新函数需要放在远程的机器上,并且假如表的修改操作并不需要在进入下
         一个对话之前马上进行。你可以使用tRFC.不需要等待每一个分开的更新程序都被执行。用户可以使用tRFC,在事务的最后进行更新。
         tRFC处理,确保了所有的更新计划都被执行了,当程序运行到commit work的时候。
         
         因为是异步调用,exporting和tables参数并不需要被指定给tRFC.
         注意:
              你不可以使用tRFC 机制,如果Exporting 参数被指定在函数接口中。你的CALL  FUNCTION 存在一个IMPORTING参数,那么会导致编译器出错。
         注意:
              你不能使用异步调用来执行call-back.
     
         WHEN the Remote System is Unavalibale.
         如果远程系统不可用,那么sap系统就运行安排执行报表RSARFCSE进行后台处理。这个报表会一直执行,直到连接到想要的系统为止。

      <6> Transactional Integrity tRFCs.完整性
          你可以执行函数模块,以后台作业的方式,在另一个R/3系统中或者一个外部的程序中。当你以这种方式进行调用,函数模块不会马上被执行,而是
          等待,直到一个COMMIT WORK被触发。
          tRFCs接收后台作业的名称,从语句IN BACKGROUND TASK的后缀中。因为需要更新数据库,LUW(逻辑工作单元) 被创建用来调用后台作业。
          所有的tRFC包含单个destination,这个destination发生在一个COMMIT WORK和下一个单独的LUW之间。在一个给定的LUW之内,所有的都调用:
          . 执行被调用的命令
          . 运行在相同的程序上下文中,在目标系统下。
          . 以单独的事务运行:他们不是commit work就是roll back.
          LUW以事务ID来识别,此ID是唯一的。这个ID可以确认一个ABAP程序,通过调用函数模块ID_OF_BACKGROUNDTASK,(你必须调用这个函数在第一次异步调用之后
          ,和相关的COMMIT WORK发生之前)。
          
          因为RFC象一个事务,所以数据库操作要不都被执行,或者假如一个函数模块被中断,所有的都返回。如果一个LUW进行成功,你就不能再次执行它了。
          在某些时候,从一个LUW中返回是必要的,(例如,一个表被锁定了)。如果要这样做,你可以调用函数模块RESTART_OF_BACKGROUNDTASK. 这个函数模块执行一个返回
          操作,并且确保LUW被在次执行,在稍后的时间里面。
          
          一般的,LUW被马上执行在COMMIT WORK之后,在一个指定的目标系统中。然而,假如你想要它在某个特定的时间开始执行,你可以设置一个开始时间,通过函数
          START_OF_BACKGROUNDTASK,这个函数也必须在这个LUW之内被调用。同样是,在第一次调用后台作业开始, 到COMMIT WORK发生之前。
          
          Checking the status of Transactional Calls
          所有的tRFC被保存在表ARFCSSTATE和ARFCSDATA,并且每一个LUW通过一个唯一的ID来识别。当一个COMMIT WORK发生,于这个ID相关的调用在相关的目标系统中
          被执行。系统函数模块ARFC_DEST_SHIP 传递数据到目标系统并且函数模块ARFC_EXECUTE执行被存储的函数调用。假如一个错误或者一个异常在某一个调用中
          发生,所有的由前面的调用产生的数据库操作都被重置,并且一个适当的错误信息被写到了文件ARFCSSTATE中.
          这里有两种方式来检测传输ID的状态:
          . 从一个ABAP程序
            函数模块ID_OF_BACKGROUNDTASK 返回LUW的ID,你调用这个模块在第一次调用后台作业的时候,和COMMIT WORK发生之前。
            CALL FUNCTION 'ID_OF_BACKGROUNDTASK' IMPORTING  TASK-ID = TID.
          
            一旦你有LUW的识别ID,你可以使用函数模块STATUS_OF_BACKGROUNDTASK 来决定tRFC的状态。

            CALL FUNCTION 'STATUS_OF_BACKGROUNDTASK'
                 EXPORTING   TID              =       TASK-ID
                 IMPORTING   ERRORTAB         =       ERTAB
                 EXCEPTIONS  
                             COMMUNICTATION   =       01
                 (如果连接不上,将会继续连接)
                             RECORDED         =       02
                             ROLLBACK         =       03
                 (Rollback 触发在目标系统中)
         
         . online
           调用事务SM58(Tools -> Adminstration -> Monitoring -> Transactional RFC).
           这个工具仅列写了处理,那些tRFCs执行不成功或者不得不被计划为批处理job的功能。这个列表包含了LUW ID和一个错误消息。
、         错误信息显示在SM58中,这些错误信息来自于目标系统。 要显示信息内容,双击信息。

           事务SM58也可以让你在不同的情况下控制你的tRFC.假如调用tRFC,在传递过程中,发生错误,你可能需要使用ROLLBACK LUW函数来手动的
           重置LUW在试图重新传输的时候。假如目标系统不可用,你可以使用后台作业函数来显示根据你的调用而创建的批处理作业。执行函数模块让你
           重新开始这个函数调用,在产生临时的错误之后(例如:一个语法错误)。

           假如一个LUW在目标系统中,成功的运行了,函数模块ARFC_DEST_CONFIRM 将被触发并且在目标系统中确认RFC成功执行。最后表ARFCSSTATE着
           ARFCSDATA的入口将被删除。

         RFC API
         你可以异步执行程序,在 'C'-implemented function modules(连接类型TCP/IP,使用事务SM59,详见Destinations类型).
         函数模块的执行一般要连接到RFC API.RFC API包含函数模块ARFC_DEST_SHIP和ARFC_DEST_CONFIRM,
         详见The RFC API.


      <7> qRFC With Send Queue
         为了保证一个LUW的次序,这个次序由应用程序所决定 , tRFC通过队列来进行序列化。这就是为什么被叫作qRFC.由于序列化,在R/3中,一个
         传递队列被创建给了tRFC.
         
         另外,应用程序想要决定他们自己在那个准确的时刻在目标系统中处理LUW。一般的,外部(非sap)系统不存在这种传递队列。qRFC连同队列
         容器,包含了一个适当的RFC library的增强,目前正在开发中(计划在下一个版本中应用)。

         Motivation
         目前tRFC运行的状况如何?
         . tRFC保证了,一个被调用的函数模块在目标系统中准确的执行一次。
         . 所有的tRFC调用都以属于一个LUW的COMMIT WORK语句结束。每一个LUW自动的接收一个TID.
         . 在一个LUW内,所有的函数模块都在目标系统在一个队列在他们被调用的传递系统中被执行。(RFC server RFC client)
         . 另外,tRFC调用单独的单元匹配到一个单独的LUW中。 这样一个sub LUW包含了仅一个tRFC调用并且不依靠目前的LUW.这种sub LUW接收
           他们自己的TID.
         . 假如在一个LUW中,几个destination被使用了,所有属于某一个destination的tRFC调用,也形成一个sub LUW.然而,因为这种集成仅发生在
           内部,就没有单独的TID分配给sub LUW了。
         
         Disadvatages of tRFC.tRFC的不足之处。
         tRFC分别处理LUW.由于有相当数量的活动的tRFC处理,这个程序在运行效率上将会下降非常明显,在传递和目标系统上。
         另外,在应用程序中定义的luws队列不能够被保留。因此,就没法保证在通过应用程序规定的队列中,执行事务。仅可以保证所有的LUW迟早会被传递。
         
         User and Availability
         应用序列tRFC,在不同环境的典型应用。
         . ALE (Application Link Enabling) 应用程序连接
         . APO (Advanced Planner and Optimizer)先进计划和优化
         . SFA (Sales Force Automation)
         qRFC 在版本4.5B可用。

         (1) qRFC With Send Queue: Overviw 概览
             这个主题内容是,处理事务队列在应用程序中的定义和可以超过一个队列被用在一个事务中。
             特性:
             qRFC的特性:
             . qRFC加强了一个序列在传递系统方。目标系统没有关于在传递系统中的序列的信息。这就允许与任何r/3,版本3.0以上的目标系统进行通信。
             . qRFC是对tRFC的增强。它传递一个LUW,仅在它没有原来的队列(关于定义在不同的应用程序中的队列)。另外,在执行一个qRFC之后,系统就
               努力开始所有的在等待中的qRFC。
             . 为了管理队列,系统需要一个队列名称和队列计数器对于每一个qRFC.每一个tRFC调用被分配到一个队列名称,这可以通过应用程序来决定。
               应用程序传递队列名称,通过调用函数模块'TRFC_SET_QUEUE_NAME'.这个函数在每一个tRFC被序列化之前,立即被调用。详见: Programming
               serialization.  一个队列名称是一个长度为24字节的文本。你可以使用任何文本,但是你不可以用*.

             . 不存在队列的配置,因为这是一个逻辑队列。不存在单独的表来保存单独的队列。在一个R/3系统中,只有一个表用来传递队列。所有的
               队列入口都被保存到了队列表TRFCQOUT.
             . 假如被序列化的tRFC 被分配到几个destionations,系统将根据每一个destionation集合他们,并且独立的处理他们每一个。这就在一个
               LUW中产生了sub luw. 我们从老的tRFC中可以知道。 既然这样,就不能保证sub LUW的队列会保持,仅可以保证的是所有的sub luw迟早会被
               处理。与老的tRFC对比,每一个sub LUW接收他们自己的TID来,进而可以容易的进行队列处理。
             . 当传递COMMIT WORK,系统决定了一个计数器来作为队列处理次序的标准.
             . 'Mixed mode' 被支持: 一个LUW可以包含普通的tRFC调用,也包含tRFC的序列化. 不管是包含,还是不包含额外的AS SEPARATE UNIT.tRFC的调用次序
               就被保证了。

     <8> Programming Serialization.
         以下程序描述了如何写qRFC,在基本模式下(就是,没有额外的AS SEPARATE UNIT 和 'mixed mode').
         Prerequisites
         . 版本在4.5B
         . 所有需要的destinations都被维护在表RFCDEST中,在RFC clicent系统中
         . 为了有一个好的运行效率,确定一个编号,并小心的分配这些队列名称.
         Procedure
         为了执行qRFC,步骤如下:
         1. 分配队列名称给并发程序调用
         2. 为了传递队列名称,调用函数TRFC_SET_QUEUE_NAME,在调用其他函数之前
         3. 调用函数,使用CALL FUNCTION ... IN BACKGROUND TASK.
         4. 重复第2,第3步(如果需要的话,也包括第1步)对所有的RFC调用.
         5. 关闭LUW使用COMMIT WORK.
         6. 重复第1 到第5步骤给应用程序的其他LUW调用。
         例子:
         REPORT ....
         ....
         DATA q_name LIKE TRFCQOUT-QNAME.
         
         q_name =  'BASIS_TEST_Q1'.
         CALL FUNCTION 'TRFC_SET_QUEUE_NAME'
              EXPORTING
                 qname = q_name.
         CALL FUNCTION 'RFC_FUNCTION_1'
              IN BACKGROUND TASK
              DESTINATION 'DEST'
              EXPROTING ...
              TABLES    ...
         ...
         q_name = 'BASIS_TEST_QM'
         CALL FUNCTION  'TRFC_SET_QUEUE_NAME'
              EXPORTING
                  qname = q_name.
         CALL FUNCTION  'RFC_FUNCTION_N'
              IN BACKGROUND TASK
              DESTINATION 'DEST'
              EXPORTING...
              TABLES....
         COMMIT WORK.
         * 下一个LUW时间.
         ...
        
         RESULT 结果
         系统保存队列信息到表TRFCQOUT.
         对于每一个COMMIT WORK,系统决定了一个计数器,这个计数器保证了事务处理的次序.
         
         系统中有个demo program: RSTRFCT0.

    <9>使用"Mixed Mode"
       特别的类型'Mixed Mode'是指qRFC和普通的tRFC调用处理在同一个LUW中。
       程序:
       当执行"Mixed Mode"在一个LUW期间内的时候,注意以下的问题:
           假如在一个LUW期间内,最先调用普通的tRFC,首先你必须调用函数模块TRFC_QUEUE_INITIALIZE.这个确保当前的LUW通过qRFC进行处理.
           假如在一个LUW期间内,最先调用的是qRFC,那么这个初始化就有函数TRFC_SET_QUEUE_NAME来完成了。
       以下程序是说明在"mixed mode"模式下,一个LUW是如何执行的。
       REPORT ....
       ....
       DATA q_name LIKE TRFCQOUT-QNAME.
       CALL FUNCTION 'TRFC_QUEUE_INITIALIZE'.

       CALL FUNCTION 'RFC_FUNCTION_1'             "tRFC call -> NO QUEUE没有队列
            IN BACKGROUND TASK
            DESTINATION 'DEST'
            EXPORTING ...
            TABLES ....
       ....
       q_name = 'BASIS_TEST_Q1'.
       CALL FUNCTION 'TRFC_SET_QUEUE_NAME'
            EXPORTING
               QNAME = q_name.
       CALL FUNCTION 'RFC_FUNCTION_2'             "qRFC call -> Q1
            IN BACKGROUND TASK
            DESTINATION 'DEST'
            EXPORTING ...
            TABLES ...
       
       CALL FUNCTION 'RFC_FUNCTION_N-1'           "tRFC call -> NO QUEUE
            IN BACKGROUND TASK
            DESTINATION 'DEST'
            EXPORTING  ...
            TABLES     ...

       q_name = 'BASIS_TEST_QM'.
       CALL FUNCTION 'TRFC_SET_QUEUE_NAME'
            EXPORTING
                qname = q_name.
       CALL FUNCTION 'RFC_FUNCTION_N'            " qRFC call -> QM
            IN BACKGROUND TASK
            DESTINATION  'DEST'
            EXPORTING  ...
            TABLES     ...
       ...
       COMMIT WORK.
      
       RESULT: 结果
       因为事务的特性,普通的tRFC调用和qRFC调用,是相同的destination,则形成一个单元. 然而,假如在当前的LUW之内,没有qRFC调用,系统将会
       集合普通的tRFC调用到一个sub LUW中。
       普通的tRFC调用包含额外的语句AS SEPARATE UNIT, 就会与分离开的LUW进行匹配,在目标系统中.
       qRFC调用,包含语句AS SEPARATE UNIT. 它的处理依赖于队列,而不是原先的 LUW.

       "mixed mode"的例子,关联到演示程序 RSTRFCT1.

   <10> Transaction Sequence and Queue Assignment
        以下例子是设计来显示,LUW的传输次序和单独的函数调用的队列分配之间的依赖关系.这个例子演示了,在某一个事务被传输之后,哪个队列被分配了。
        试验演示程序RSTRFCT3.
        
        Sample Scenario 例子设定
        队列的使用方法
        这个图表显示了由应用程序规定的事务次序,也显示了各自的队列应用在单独的函数调用上.
        例如: 事务T3 包含了2 个 qRFC调用,并分配给了队列Q1和另两个qRFC调用分配给了Q3.
              相反,事务T6仅包含了qRFC调用,使用语句AS SEPARATE UNIT,分配给了队列Q6.
              T1  -> Q1  Q1  Q2  Q2  Q3  Q3  Q4  Q4
              T2  -> Q5  Q5  Q6  Q6  Q7  Q7  Q8
              T3  -> Q1  Q1  Q3  Q3
              T4  -> Q2  Q2  Q4  Q4
              T5  -> Q6  Q7S Q8S Q7  Q7
              T6  -> Q6S
              T7  -> Q7S
        
        队列的分配
        在传输之前
        从队列的使用上看,上面的例子中,队列的最初的分配结果如下:
        Q1  T1Q1N1  T1Q1N2   T3Q1N1   T3Q1N2
        Q2  T1Q2N1  T1Q2N2   T4Q2N1   T4Q2N2
        Q3  T1Q3N1  T1Q3N2   T3Q3N1   T3Q3N2
        Q4  T1Q4N1  T1Q4N2   T4Q4N1   T4Q4N2
        Q5  T2Q5N1  T2Q5N2
        Q6  T2Q6N1  T2Q6N2   T5Q6N1   T6Q6S1
        Q7  T2Q7N1  T2Q7N2   T5Q7S1   T5Q7N1   T5Q7N2   T7Q7S1
        Q8  T2Q8N1  T5Q8S1

        在传递T1之后.
        在事务T1被成功传递之后,事务T3和T4准备进行传递了。
        这就导致了下面的队列的分配:
        Q1
        Q2
        Q3
        Q4
        Q5  T2Q5N1  T2Q5N2
        Q6  T2Q6N1  T2Q6N2   T5Q6N1    T6Q6S1
        Q7  T2Q7N1  T2Q7N2   T5Q7S1    T5Q7N1    T5Q7N2    T7Q7S1
        Q8  T2Q8N1  T5Q8S1
        
        首先,T1的调用被传递在所有的包含T1的队列中(Q1,Q2,Q3和Q4).
        所有其他独立的事务,与T1共享部分队列的也准备传递,在这之后.
        既然这样,就有事务T3和T4,被处理.
        事务T2,T5,T6和T7仍然处于等待状态,直到T3和T4被成功的传递为止.
        在这之后,等待的事务就开始自动的处理,一个接一个.


   <11>工具
       Passing Queue Names:传递队列名称
       TRFC_SET_QUEUE_NAME
       这个函数模块传递一个队列的名称,在tRFC调用之前.并且规定了当前的LUW必须被处理,通过qRFC.
       队列名称传递,仅在并发的tRFC调用时有效.
       
       Reading Queue Entries: 读取队列的入口
       TRFC_GET_QUEUE_INFO  和 TRFC_GET_QUEUE_INFO_DETAILS
       使用这些函数模块,来读取当前的一个或者全部队列的信息从表TRFCQUOT中,以复杂或稍微简单的方式.
       
       RSTRFCQR.(是程序)
       这是abap程序使用的两个上面提到的函数模块,来显示当前的传递的队列表TRFCQUOT的内容.
       
       RSTRFCQD.(是程序)
       这个是abap程序,删除所有的单个或者全部事务对应的入口.使用这个程序来进行测试目的或者显示紧急情况.假如你删除掉一个事务的
       入口,那么这个事务就不在序列化.你就不得不手动来启动,如果要再次启动.

      Initializing In 'Mixed Mode'
      TRFC_QUEUE_INITIALIZE
      调用这个不需要参数的的函数模块,在qRFC LUW的开始的时候,在"mixed mode"模式中(即使用tRFC也使用qRFC). 调用这个函数,规定了,当前的
      LUW必须通过qRFC传递.然而,这个仅在最先调用普通的tRFC的时候有必要.假如最先调用一个qRFC,初始化就由函数模块TRFC_SET_QUEUE_NAME,来处理.
      看演示程序RSTRFCT1.

      SM58
      事务SM58,你可以使用tRFC的监控器来显示和编辑tRFC的事务,现同样允许处理qRFC事务.


      Stopping Queues, Continuing Them, and Querying Their Status
      你可以停止并且继续处理一个或者更多的队列(使用普通的规范).另外,你看查询一个队列的状态.使用下面的函数模块:
      
      TRFC_QOUT_STOP.
      指定一个队列名称(单个或者一般的,例如:BASIS_TEST_*)和一个destination,来停止处理一个或者更多的队列.依靠FORCE参数,你可以马上停止处理
      (参数FORCE = 'X)或者处理在这个时刻存在于队列中的所有的请求,然后在停止。你也可以停止一个空的队。在这种情况下,
      所有分配到这个队列的事务不会马上被传递。看演示程序RSTRFCQ1.

      TRFC_QOUT_STATE
      指定一个队列的名称和一个目标地址(destination),目的是为了查询这个队列的状态。看演示程序RSTRFCQ2.
      一个队列可以是以下状态中的一个:
           . RUNNING 运行
           . CPICERR 
           . SYSFAIL 系统错误
           . STOPPING 正在停止
           . STOP     停止
           . WAITSTOP 等待停止
    
      状态SYSFAIL,是由一系列错误产生的,并且由目标系统的R/3内核或者被调函数模块的一个异常触发。 在这个状态中,队列仍然保留。但不会自动的重新运行。
      你可以使用SM58来重新传递LUW或者删除它。假如你删除了它。系统自动的删除相关的入口,在队列表TRFCQOUT中。
      在状态CPICERR,存在一个自动的循环依靠在SM59中的destination配置.(默认设置为"Yes")。

      TRFC_QOUT_RESTART
      指定一个队列的名称(单个或者普通的,例如BASIS_TEST_*)和一个destination,目的是为了可以继续处理一个或者更多的队列,不管这些队列是否在之前被一个队列
      停止函数模块(参数FORCE)或者被状态CPICERR或者状态SYSFAIL停止.看演示程序RSTRFCQ3.

      TRFC_QOUT_RESTART_COND
      指定一个队列名称(单个或者普通的,例如BASIS_TEST_*)和一个destination,目的是为了,当出现处理一个或更多的其他队列被中断的时候,继续处理一个或更多
      的队列。调用这个函数,将自动的停止在此刻正在进行中或准备进行的的队列,假如之前没有其他停止调用(STOP CALL)发生(依赖于参数FORCE的设置)。
      看演示程序RSTRFCQ4。
      
      Sample Programs
       . RSTRFCT0, RSTRFCT1, RSTRFCT2, 和 RSTRFCT3是qRFC的例子或者测试程序,
       . 通过RSTRFCQ1, RSTRFCQ2, RSTRFCQ3, 和 RSTRFCQ4,你可以停止处理一个或者更多的队列,继续其他处理,通过有条件或者无条件调用。或者查询队列的状态。

   <12> Using Asynchronous Remote Function Calls
      异步远程调用(aRFCs)与tRFCs类似,在异步远程调用时,使用者不需要等待这些他们的完成,在继续调用对话的时候。他们有三个特性,来区别于tRFCs:
       . 当调用者开始一个异步调用,被调函数所在的服务器必须可以接受请求。aRFCs的参数不是登陆到数据库,而是直接传递到了服务器上。
       . aRFCs 允许用户与远程系统,持续一个交互式的对话。
       . 调用函数所在程序可以接收到aRFCs处理的结果。
      你可以使用aRFC,无论何时,你需要建立与一个远程系统的通讯,但是不需要等待函数的处理结果,在继续其他处理的时候。
      aRFCs 也可以传递到相同的系统中。在这种情况下,系统开启一个新的对话(或者窗口),并且允许你来回的传递数据在调用会话和被调会话之间。
      
      要开始一个aRFC,使用下列的语法:
      CALL FUNCTION RemoteFunction  STARTING NEW TASK taskname
      Destination ...
        EXPORTING ...
        TABLES    ...
        EXCEPTIONS ...
      
        下面可用的调用参数:
          . TABLES
            传递内表的引用。所有的函数模块,tables参数,必须包含数据。
          . EXPORTING
            传递字段参数和字段字符,从调用程序到函数中。在函数模块中,先前相对应的参数被定义为import参数。
          . EXCEPTIONS
            请看 使用预先定义的异常

          RECEIVE RESULTS FROM FUNCTION func被使用在一个子程序中,来接收aRFC的结果。下面的接收参数可用:
          . IMPORTING
          . TABLES
          . EXCEPTIONS
          额外的KEEPING TASK 避免了一个异步连接在接收完处理结果数据后,被关闭。相关的远程上下文(roll area)被保持,以用来重复使用,
          直到调用者关闭连接。

          异步调用一个事务并且将它显示在一个形式对话框中:
          DATA: MSG_TEXT(80) TYPE c.             "Message text
          ...
          * Asynchronous call to transaction SM59  ->
          * Create a new session
          CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
               STARTING NEW TASK 'TEST'
               DESTINATION 'NONE'
               EXPROTING
                  TCODE = 'SM59'
               EXCEPTIONS
                  COMMUNICATION_FAILURE  = 1  MESSAGE MSG_TEXT
                  SYSTEM_FAILURE         = 2  MESSAGE MSG_TEXT
          
           IF SY-SUBRC NE 0.
               WRITE: MSG_TEXT.
           ELSE.
               WRITE: 'O.K.'.
           ENDIF.

    
    <13> Calling Requirements for Asynchronous RFCs
         当你调用一个远程函数,使用可选择后缀STARTING NEW TASK, 系统在一个新的会话中开始这个函数。相对于等待远程调用的结束,在aRFC中,用户在目标系统中
         一完成函数模块的调用就可以继续其他处理。

         列如:远程被调用函数模块可以显示一个新的屏幕,通过使用CALL SCREEN, 允许用户进入一个对话,这个对话直接连接他或者她到一个远程系统中。
         Client System
         CALL FUNCTION 'TRAVEL_CREATE_FLIGHT'
              STARTING NEW TASK 'FLIGHT'
              DESTINATION 'S11'.

         Server System
         FUNCTION TRVEL_CREATE_FLIGHT.
              CALL SCREEN 100.
         ENDFUNCTION.
         假如你不指定一个destination,aRFC机制在调用系统中开始一个新的会话。
        
                  Warning: 
                  你不允许使用IMPORTING,当调用一个aRFCs的时候。(因为返回的结果,并不由原先的函数接收,而是通过其他来接受,下面将讲述异步接受)

         Receiving Results from an Asynchronous RFC
         为了从一个异步调用函数中,接收结果,使用下面的语法:
         CALL FUNCTION remoteFuntion
              STARTING NEW TASK Task
              PERFORMING RETURN_FROM ON END OF TASK.
         一旦被调用函数完成,在调用程序的下一个对话步骤(例如:AT USER-COMMAND),将引导系统进入到子程序中,这个子程序将用来检测结果。这个子程序
         包含一个特殊的饿语法,并且在使用时,必须使用的一个参数,是上面的task 名称。
         Client System
         CALL FUNCTION 'TRAVEL_CREATE_FLIGHT'
              STARTING NEW TASK 'FLIGHT'
              DESTINATION  'S11'
              PERFORMING RETURN_FLIGHT ON END OF TASK.
         ...
         FORM RETURN_FLIGHT USING TASKNAME.
              RECEIVE RESULTS FROM FUNCTION 'TRAVEL_CREATE_FLIGHT'
                      IMPORTING   FLIGHTID = SFLIGHT-ID
                      EXCEPTIONS  SYSTEM_FAILURE MESSAGE SYSTEM_MSG.
              SET USER-COMMAND 'OKCD'.
         ENDFORM.
         
             . 假如一个函数模块没有返回结果,那么额外的PERFORMING RETURN_FORM ON END OF TASK可以被省略。
             . 假如一个异步调用,调用了几个连续的函数模块,使用相同的destination, 你必须分配一个不同的task name给每一个函数。
             . 一个调用程序开始一个aRFC,使用了PERFORMING, 但是不能够转换roll areas或者转变为一个内部模式。这是因为异步函数模块调用的返回,不能
               被传递到相关的程序中。你可以执行一个roll area,使用SUBMIT 或者 CALL TRANSACTION.
             . 假如执行异步调用的调用程序被停止,不管它正在接受返回信息,这些来自异步调用的返回信息不允许被传递。
             . 你可以使用WAIT语句,连同PERFORMING form ON END OF TASK,来等待先前开始的异步调用的返回。在这种情况下,WAIT语句必须在相同的程序上下文。

         
         Receiving Results from an Asynchronous RFC
             . 在WAIT之后,程序继续进行下面处理。 想要获取更多的WAIT语句信息,查看ABAP编辑器中的在线帮助。

         关键子RECEIVE的触发,仅在使用函数模块调用CALL FUNCTION func STARTING NEW TASK taskname.
         如果函数模块没有返回值,那么这个部分就不需要被定义了。
         
               注意:关键子RECEIVE在R/3版本3.0 以上可用。因此,server,client系统,必须都是在版本3.0以上。
                    如果需要更多的信息,请看ABAP编辑器中的在线帮助。

         语句SET USER-COMMAND 'OKCD'的效果是, 就象用户按了按钮一样。这意味着当前的列表位置以及关闭位置将会被考虑。

               注意: 回调不被支持。No call-backs are supported.
               警告: SET USER-COMMAND 'OKCD' 语句代替了REFRESH SCREEN 命令。REFRESH SCREEN 不在被维持,因此不要用。
               
               例子: 
                     DATA: INFO LIKE RFCSI,
                     * Result of RFC_SYSTEM_INFO function
                           MSG(80) VALUE SPACE.
                     * Exception handling
                     CALL FUNCTION 'RFC_SYSTEM_INFO'
                          STARTING NEW TASK 'INFO'
                          PERFORMING RETURN_INFO ON END OF TASk
                          EXCEPTIONS
                              COMMUNICATION_FAILURE   = 1  MESSAGE MSG
                              COMMUNICATION_FAILURE   = 2  MESSAGE MSG.
                          
                     IF SY-SUBRC = 0.
                        WRITE: 'Wait for reply'.
                     ELSE.
                        WRITE MSG.
                     ENDIF.
                     ...

                     AT USER-COMMAND.
                     * Return from Form routine RETURN_INFO via SET USER-COMMAND
                        IF SY-UCOMM = 'OKCD'.
                           IF MSG = SPACE.
                               WRITE: 'Destination = ', INFO-RFCDEST.
                           ELSE.
                               WRITE MSG.
                           ENDIF.
                        ENDIF.
                      ...
                     FORM RETURN_INFO USING TASKNAME.
                        RECEIVE RESULTS FROM FUNCTION 'RFC_SYSTEM_INFO'
                                IMPORTING  RFCSI_EXPORT = INFO
                                EXCEPTIONS
                                   COMMUNICATION_FAILURE = 1 MESSAGE MSG
                                   SYSTEM_FAILURE        = 2 MESSAGE MSG.
                        SET USER-COMMAND 'OKCD'.
                     ENDFORM.

             
       Keeping the Remote Context
       在获取异步调用的结果的子程序中,额外语句KEEPING TASK,避免了在接收完数据后,关闭异步连接。
       FROM RETURN_INFO USING TASKNAME.
          RECEIVE RESULTS FROM FUNCTION 'RFC_SYSTEM_INFO'.
          KEEPING TASK
       ...
       ENDFORM.
       相关远程上下文(roll area)被保持,一直到调用者关闭这个连接。假如你指定了相同的作业名称,你可以重新使用远程上下文和roll area.
       
       假如远程调用函数执行的是交互式的任务,如处理列表或者屏幕,屏幕会一直显示直到调用程序中断为止。假如远程调用处于调试模式下,这种模式
       是可见的,直到调用对话被关闭。

                注意: 仅在你想要重复使用当前的远程上下文为后续的异步调用服务时,你可以使用额外的KEEPING TASK.
                       保持一个远程上下文会增加内存的使用,以及降低程序执行效率,因为,在系统中,要进行额外的roll area,管理。

       
       Parallel Processing with Asynchronous RFC
       为了完成系统的负载平衡,你可以使用destination additions,在parallel task中,执行函数模块,在任何应用服务器,或者一个预先定义的应用服务器组。
            警告: 
            平衡处理被执行,使用一个特殊的异步RFC变量。这在你使用仅正确的变量给你自己的平衡处理程序的时候,非常重要:
            CALL FUNCTION STARTING NEW TASK DESTINATION IN GROUP keyword.
            使用其他的aRFC变量,围绕内置的安全装置在正确的关键字下。
        
       更加详细的讨论在以下子分部中:
       .  平衡处理的先决条件
       .  进行平衡处理的函数模块和abap关键字
       .  在平衡处理中的资源管理

       Prerequisites for Parallel Processing : 平衡处理的先决条件
       在你执行平衡处理之前,确认你的应用程序和你的R/3系统满足以下要求:
       .  逻辑独立工作单元
          在parallel 处理中,被执行的数据处理作业必须是作业的其他实例的独立逻辑。 更确切的说,可以被执行的作业,不包含关联到其他记录的相同的数据集,
          (就是,数据是单享的),并且作业是不依靠其他parallel操作的结果的。例如: parallel处理就不合适处理这样的数据,这些数据必须被持续处理的,或者
          是在某个处理中的数据条目,依赖于处理中的其他数据条目。

          通过定义,无法保证,数据将被处理在一个特定的顺序中,在parallel处理中,或者一个特定的结果将被可用,在处理时候的一个给定的时刻上。
       .  ABAP 需求
          - 你所调用的函数模块必须被设置为可以外部调用。这个属性是指定为Remote function call supported, 在函数模块定义的时候。
          - 被调用的函数模块不允许包含一个函数调用,作为destination 的返回"BACK".
          - 调用程序不应该转变为一个新的内部session,在做一个异步RFC调用的时候。更确切的说,你不应该使用SUBMIT或者CALL TRANSACTION,在使用
            CALL FUNCTION STARTING NEW TASK 之后的报表中。
          - 你不可以使用CALL FUNCTION STARTING NEW TASK DESTINATION IN GROUP keyword 来开始一个外部程序。
       
       
      Parallel Processing with Asynchronous RFC
         为了处理来自parallel jobs的作业,在你R/3系统中的服务必须有至少3个对话工作处理。

      
      Function Modules and ABAP Keywords for Parallel Processing
      你可以执行parallel处理, 在你的应用程序中,通过使用以下的函数模块而ABAP关键字:
         .  SPBT_INITIALIZE: 可选函数模块。
            用来决定进行parallel处理的资源是否可用。
            你可以完成以下:
            - 检测你已指定的parallel 处理group是否正确
            - 找出多少工作处理可用,这样,你可以更有效的设置数据包的大小。

         .  CALL FUNCTION <function> STARTING NEW TASK <taskname> DESTINATION IN GROUP:
            使用这个abap关键字,使R/3系统,执行函数调用在parallel模式下。 具有代表性的,你将可以放置这个关键字在一个循环中,在这个循环你可以把
            数据分离开, 放入一个包中。你可以传递要进行处理的数据,以一个内表的形式(EXPORT,TABLE参数)。
            
            注意:你的RFC调用,使用CALL FUNCTION进行处理,工作进程类型是DIALOG.这个DIALOG只有一个对话步骤的时间(大约300秒,系统参数 rdisp/max_wprun_time)
            应用到RFC调用中。记住这个限定,当你想要划分数据到parallel处理的时候。

         . SPBT_GET_PP_DESTINATION: 可选择函数模块
           在CALL FUNCTION keyword之间马上被调用,用作获取服务的名称。 parallel处理作业将运行在这个服务上。
         
         . SPBT_DO_NOT_USE_SERVER:  可选函数模块
           不包含一个特定的服务,进行使用。
       
         . WAIT: ABAP 关键字
           WAIT UNTIL <逻辑表达式>
           键入你想要等所有的异步parallel作业被创建,通过使用CALL FUNCTION来返回的时候,就需要了。
           或许仅在CALL FUNCTION包含PERFORMING ON RETURN 的情况下被使用。

         . RECEIVE: abap关键字
           RECEIVE RESULT FROM FUNCTION function
           假如你希望接收来自aRFC的处理。 RECEIVE 重新获取 IMPROT和TABLE参数,连同信息和返回代码。(MESSAGE SY-SUBRC)

     
    Managing Resources in Parallel Processing
    你可以使用以下的目标,增加运行parallel执行函数模块。

    在一个预先定义的应用服务组:
          CALL FUNCTION RemoteFunction STARTING NEW TASK taskname
               Destination IN GROUP groupname
    汇总当前所有可用和活动的服务:
          CALL FUNCTION RemoteFunction STARTING NEW TASK Task
               Destination IN GROUP DEFAULT.

    增加的语句,首先决定了当前可用的资源的数量。在每一个应用服务器上的,可用于执行异步调用的资源,依靠当前系统的负载。

    应用程序开发者,在生产机上,对可用的RFCs groups负有责任。更详细的请看,如何维护RFC groups.
   
    在确定可用资源后,异步调用被执行在一个可用的应用服务上。 假如没有资源可用,在一个特定的时间上,系统会执行异常程序RESOURCE_FAILURE(请看Exceptions异常)。
    在这种情况下,一个异步函数模块的调用,这个异常必须被应用程序所处理。

    确定一个RFC group的可用资源的过程如下:
    首先,系统确定发送队列的长度。假如它比全部的长度大10%,服务就没有可用资源。假如它稍微小点,系统创建可用的的当前自由对话的进程数量减去2(作为其他目的的
    贮备,例如:登陆到系统或者管理程序)。
    因而,一个应用服务必须有至少3个对话进程,假如RFC parallel 处理要被考虑的话。

           注意:
              . 在当前,一个程序中仅一个RFC group被支持paralle执行异步调用。使用两者(DESTIANTION IN GROUP <groupname> 和 DESTINATION IN GROUP DEFAULT)
                在一个程序中是不被允许的。
              . 异常程序 RESOURCE_FAILURE 仅被触发在连接aRFCs的时候,使用语句DESTIANTION IN GROUP groupname 和 DESTINATION IN GROUP DEFAULT.
              . 推荐使用一个RFC group,当有足够的资源进行parallel处理,异步调用。

 

  <14> Checking Authorizations for RFC.  RFC权限检测
       假如系统参数auth/rfc_authority_check 被设置为(值1),那么系统自动的检测,在CALL FUNCTION关键字,用户是否有调用RFC的权限。
       
       RFC权限对象是S_RFC,检测使用RFC权限。一个用户是否有权力运行属于某个组的函数模块,

       你可以测试一个用户的RFC权限使用函数模块 AUTHORITY_CHECK_RFC.这个函数模块返回RC = 0,假如用户被授权。函数模块不能检测,一个权限检测是否发生。

       
 <15> Using Pre-Defined Exceptions for RFC : 使用预先定义的RFC异常
      当任何异常发生,在被叫函数模块中,通过语句 PERFORMING form ON END OF TASK 处理, RFC接口定义了两中类型的异常,他们是:
      .  SYSTEM_FAILURE:
         这个异常报告所有的故障和系统的问题,在远程系统上。
      .  COMMUNICATION_FAILURE
         这个异常在,当一个连接或者通信失败时发生。它不报告系统的问题,(例如:不正常的中断)。

      Requesting Error Messages: 所需要的error信息
      在你调用的函数模块中,你应该使用异常处理任何错误报告,而不是MESSAGE 关键字。
      CALL FUNCTION RemoteFunction
           DESTINATION 'hw1071_53' 
           EXCEPTION ...
           IMPORTING ...
           TABLES    ...
           EXCEPTIONS
              SYSTEM_FAILURE = 1 MESSAGE msg
              COMMUNICATION_FAILURE = 2 MESSAGE msg

      系统设置了msg变量来获取系统信息。你可以显示这个信息或者写入到一个文件中。不要试图解释信息文本,在你的程序中。

 <16> Writing Remote Function Modules In ABAP
      这部分提供了写RFC的详细说明。

      Steps for Implementing Remote Function Modules
      步骤:
      1. 注册RFC到服务系统中。
         SE37, 设置为REMOTE CALL.
      2. 写函数代码
      3. 在RFC client system上定义RFC server的 destination.
         保存在表RFCDES上,使用事务SM59.如何维护,请看主题:维护远程目标地址。
      
      Programming Guidelines: 程序指导
      声明参数:
          下面的部分描述了一些当你写一个远程调用函数需要记住的地方。

      Declaring Parameters
      对于普通的函数(非远程),假如一个参数没有被定义为一个ABAP数据字典字段,那么它将使用实际的参数的数据类型在运行时。

      但是,一个远程函数模块,这些信息是不可用的。那么就产生了一个结果,所有的参数字段必须被定义为相关的字段。也就是说,abap的数据字典字段。(这里包括
      IMPORTING,EXPORTING,和TABLES参数。)
      
      对于字符结构或者字段,调用者的参数不需要如被调用函数期望的那么长。当输入参数长度短,RFC简单的就以零垫补。这就意味着ABAP字典定义的字符参数不需要
      严格的相同在调用方和被调用方。(然而,调用者参数不会比在被调用方期望的那样长)。

      Writing for Transaction Execution
              警告: 这里有两个严格要求,在写远程函数的时候,
                  . 事务方式的调用不能返回参数的值。结果,这些函数的接口不允许指定任何EXPORT 参数。
                  . 以事务方式调用的函数,不可以执行call-backs: 调用者的上下文仍然存在,就不是很必要,当call-back被接替转播到原先的系统。

      
      Reporting on Exceptions
      你可以唤起异常在一个远程函数中,就象你在本地函数中唤起异常那样。
      自从系统以内部方式唤起COMMUNICATION_FAILURE和SYSTEM_FAILURE,那就没有理由在你的程序中唤起它们。MESSAGE关键字仅为相关联系统异常的描述。
      因此你需要将他们编入你的函数中。

      Calling Other Remote Functions
      一个远程调用函数可以调用其他的函数,就象一个普通的函数一样。
      特别的是,它可以使用call-back特性来调用原先系统中的调用者。

  <17>Debugging Remote Function Modules
      当测试一个ABAP 到abap的RFC调用,你可以使用abap调试器来监控,在远程系统中,RFC函数的执行。静态的断点,单步执行,变量查看和源代码显示都可用。

      进行远程调用的时候,ABAP编辑器(包括调试器接口)运行在原先系统中的,数据值和其他运行远程调用需要的信息从远程系统中传递进来。

  Maintaining Remote Destinations
  选择Tools -> Administration -> Administration -> Newwork -> RFC destinations.
  具体的解释在以下主题:
  Types of Destinations 目标地址的类型
  Displaying,Maintaining 和 Testing Destinations   显示,维护和测试目标地址
  Entering Destination Parameters                  输入目标地址参数
  Maintaining Group Destinations                   维护目标地址组
  
  Displaying,Maintaining and Testing Destinations
  为了显示,创建或者修改目标地址,选择Tools -> Administration -> Administration -> Newwork -> RFC目标地址 或者 输入事务代码SM59.

  远程目标地址被保存在表RFCDES中。RFCDES表描述了远程函数调用的逻辑目标地址。

  直接维护表RFCDES是不可能的.
      
          注意: 
               你可以进入逻辑目标地址通过执行IMG,选择Tools -> AcceleratedSAP -> Customizing -> Execute Project -> SAP Reference IMG.
               在执行指南,张开层次结构。
               Basis
                Application Link Enabling (ALE)
                 Sending and Receiving Systems
                   Systems in Network
                       Define Target System for RFC Calls

  
  显示目标地址
  创建目标地址 
      在目标地址的查看屏幕中(事务代码SM59),连接类型和所有存在的目标地址都显示在一个树形结构。
      所有可用的连接类型都在Types of Destinations有注释。
      为了新建RFC目标地址,按创建按钮。一个新的屏幕会显示出来,包含空的字段,需要你填入。
      假如你想要创建一个新的目标地址
      当你创建一个远程目标地址,你可以指定一个特别的应用服务或者一组服务来进行负载平衡。
  修改已存在的目标地址
      事务代码SM59进入。双击进入修改。
  测试目标地址
      为了测试目标地址,选择适当的函数从测试菜单中。
      . 连接(通过测试连接按扭也可用)
      . 授权(检测登陆数据)
      . 本地网络(提供一列应用服务)

  输入目标地址的参数
  除了RFC的目标地址,你可以输入以下信息:
     Technical settings
      . Connection type:连接类型
           输入一个已经存在的连接类型或者选择一个, 通过字段输入帮助。
      . Trace: 追踪
           标注一个追踪选项,记录RFC通讯日志并保存到一个文件中。你可以显示这个文件,即可以在调用系统也可以在接受系统,使用报表RSRFCTRC.
      . Load balance:负载平衡
           假如你选择负载平衡,你必须指定以下的信息:
           - Target system:目标系统
           - Message server(登陆到目标系统,然后选择Control->control Panel从CCMS主菜单上。提供信息服务的服务)
           - Group(of servers)
           另外,你还需要指定以下信息:
           - Target host   目标系统
             目标系统的服务器名称,你需要用它来作为端口.
           - System number 系统编号
             通讯服务被应用到目标系统,为了获取它,选择Tools -> Administration -> Monitor -> System Monitor -> Servers.
   
    Security Options: 安全选项
    下面的选项仅可用于一些连接类型:
     . Trusted system(for type 3 only)
          假如目标系统是一个可信赖的系统,选择yes。
     . SNC (安全网络通讯,近用于类型3和T)
          假如你有一个活动的SNC-supported安全系统,你可以激活额外的安全选项,通过Destinaions -> SNC 选项可以设置。
    
    登陆:
     . 语言
        系统被使用的语言
     . Client
        Client 代码
     . User
        被用来远程登陆的用户名,假如与当前的用户名不同。
     . Password
        用户密码
     . Current user
        当前用户名被使用来进行远程登陆。
     . Unencrypted password(2.0)
        假如目标系统在R/3系统的版本是2.0,密码就不需要被加密了。


     Types of Destinations
     每一个目标地址都有一个连接类型字段,这个连接类型,告诉系统,这是何种系统连接:
     . R/2 连接(Type 2)
       Type 2 入口指定到R/2系统。不需要其他详细的说明了。例如: 当你创建一个类型2的入口,你仅仅需要给出服务器的名称;所有的通讯信息
       已经被保存到了表中。然而,假如需要,你可以指出登陆信息。

     . R/3连接(Type 3)
       Type3入口指定给R/3系统。 当你创建了一个类型3的入口,你必须给出服务器名称和通讯服务。你也可以指定登陆信息,假如需要的话。从R/3系统,版本
       3.0以上,你也可以负载平衡选项,假如需要的话。
       从R/3系统,版本3.0以上,指定一个应用服务从R/3信息系统。然后,应用服务通过负载平衡处理来决定。这可以应用到R/3系统也可以应用到r/3 系统
       的外部调用。

     . 内部连接(Type I)
       Type I 入口指定到R/3系统,连接相同的资料库,作为当前系统。这些入口是预先定义的, 并且不能被修改。这些入口名称与SAP Message服务上的一直
       (事务SM51)
       例如:入口名称: hs0010_k11_23
             - hs0010 = host name 
             - k11    = system name(data base name)
             - 24 = TCP-server name

     . 逻辑目标地址Logical destinations(Type L)
       代替指定一个系统的连接,类型L 入口关联到一个物理目标。类型L目标地址也可以关联到其他的类型L入口。一个类型L入口使用信息在"referred-to"
       入口,并且添加它自己的更多的信息。特别的,"referred-to"入口给出了服务器信息,并且类型-L入口给出了登陆数据。你也可以设置用户名称,一个
       清楚的密码,一个登陆语言或者一个清楚客户端。
       一个类型L入口可以连接到其他的L类型入口。
       例如 入口名称: k11_sd 或者 k11_01
                    - k11 = 目标地址的名称,
                    - SD 或者 01:

      . 通过ABAP驱动连接(Type X)
        Type X入口指定了系统中,已经临时安装的设备驱动在那里。当你创建一个类型X 的入口,你必须给出ABAP设备的驱动。
      
      . TCP/IP连接(类型T)
        类型T的目标地址连接到外部程序,这些外部程序使用RFC API来接收RFCs. 激活类型可以为Start或Registration.
        
        假如是Start,你必须指定程序中的服务器名称和路径名称。

        Activation Type Start
        通信方法依赖于你如何选择程序的定位:
        - Explicit host. 外在的主机
          在这种情况下,程序被启动,不是通过默认的系统的网关就是通过明确地被指定的网关(gwrd),选择remote shell.
          保证有网关处理的电脑可以进入到指定的电脑上,通过输入/etc/ping <host name>.

          为了能够运行另外台电脑中的程序,通过使用remote shell, 目标系统不惜满足某些条件。
          . 网关处理的用户的ID必须存在并且一个文件叫.rhosts的必须显示在用户的根目录中。
          . 文件.rhosts必须包含调用电脑的名称。
          为了检测这个,登陆包含网关处理的电脑,使用合适的用户ID并且输入命令remsh <host name> <program name>. <host name>和<program name>必须相同在
          SM59中。(假如你调用一个RFC服务程序,不包含任何的参数,RfcAccept call 总是会返回一个错误代码(RFC_HANDLE_NULL) 并且程序立即被中断了。)

        - Application server
          在选择应用服务和指定到你的程序,你可以从SAP应用服务中开始程序。
          首先,确保可以从SAP应用服务中进入到程序,并且SAP应用服务有开始程序的权限。

          为了检测这些,使用SAP应用服务的用户进行登陆。假如可能,改变SAP应用服务的工作文件夹(/user/sap/.../D.../work)并且努力从这里手动开始SAP应用服务。
          (在是上面的情况下,假如你调用一个RFC server 程序,没有带任何参数,RfcAccept call总是会返回一个错误代码(RFC_HANDLE_NULL)并且程序立即被终止)。
        
        - Front-end workstation
          在选择Front-end workstation 并且指定到你的程序中,你可以从SAPGUI中启动程序。
          确保你可以通过SAPGUI进入到程序中。

       Types of Destinations
          确保SAPGUI有权限启动程序。
          为检测这个,简单的调用RFC server 程序在你的环境下。
          函数模块的调用也可以用事务处理(CALL FUNCTION ... IN BACKGROUND TASK DESTINATION...).
       
          Activation Type Registration
         假如激活的类型是Registration,你必须识别一个已经注册的RFC程序。通过一个SAP网关,一个RFC server 程序,可以被注册到这个ID下,然后等待来自不同SAP
         系统的RFC 调用。
         例子: SERVER_EXEC.

    . Type M
         类型M的入口,是异步RFC连接到R/3系统,通过CMC(protocol x.400).
    
    . Type S
         类型s与类型2相对应,除了目标地址是SNA或者APPC.


    Maintaining Group Destinations: 维护目标地址组
    为了实现目标系统的负载平衡,你必须定义一个应用服务组作为RFC的destination.当处理平衡作业的时候,你可以使用这个group destionation来连接异步RFC.

    每个应用服务的可用资源依赖于当前系统的负载。
    
    为了显示和维护RFC组,处理如下:
    1. 在RFC destionation 浏览屏幕中,选择RFC ->RFC groups.
       你将看到:
       - 任何一个RFC组的名称已经被定义了。
       - 一个实例的列表(主机,系统,实例编号)在你的R/3系统中。
       - 每台服务器的当前状态(活动或否)

    2. 为了定义一个RFC组,选择Edit->create.输入一个服务器组的名称和一个实例对象在对话框窗口。
       为了添加实例到一个已经存在的组中,双击组名并输入新的实例对象到对话框窗口中。

       通过创建重复的入口,你可以分配一个服务器到多个组中。既然这样,使用组的作业将由空闲的进程完成,在共享的服务器上。

       使用例子:
           你可以使用组来允许不同的平衡处理作业运行,在相同的时候,不通过相同的服务器完成。既然这样,不同的组被使用来操作作业,被指定到不同的服务器上。

           你也可以使用组来分开处理作业,在用户对话活动的服务器上。既然这样, 被用来处理的组可以命名为servers而不同于那些提供给用户的登陆组。

  <18> Maintaining Trust Relationships Between R/3 Systems
       R/3系统可以在彼此之间建立信赖关系。
       假如一个调用的R/3系统被被调系统认作值得信赖的系统,那就不需要提供任何密码。
       进行调用的系统必须被注册到被调系统中,作为一个值得信赖的系统。

       维护创建:SMT1. 
       不详述.

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值