0

我在外部调用一些 RFC 模块,该模块调用其他模块并在调用堆栈中计算一些值并将其保存到内存中,然后最后读取该值并返回给外部调用者。每次计算可能不同,因此我们需要相应地读取内存区域。

目前案件的并发症是:

  1. 模块总是从同一个系统调用,所以调用者总是相同的
  2. 调用FM的用户是相同的,所以用户也总是相同的
  3. 连接将被重用,就像这里描述的一样,所以 ABAP 内存也将是相同的

这个想法是使用仅对当前调用唯一的 ID 写入内存,而不是之前的调用,即内存中的值将始终相关。

让我用我创建的这个简单的 FM 来说明这个案例。只有在当前调用中设置了该值,模块才会返回该值,即只有相关的值。

FUNCTION Z_MEM.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  EXPORTING
*"     VALUE(E_PAR) TYPE  CHAR50
*"----------------------------------------------------------------------

  DATA id LIKE sy-timlo.

  IMPORT id FROM MEMORY ID 'MAN'.

  IF id IS INITIAL.
  
    id = sy-timlo.
    EXPORT id TO MEMORY ID 'MAN'.
    e_par = id.
    
  ENDIF.

ENDFUNCTION.

我从外部循环测试了 20 次,得到:

>>> 154251


    ...
>>> 

因此,内存按预期重用,所有进一步的运行可能会消耗错误的值。

我在这里看到的可能解决方案:

  1. 设置JCo客户端每次关闭RFC连接,这样每次都会创建新的ABAP内存区域
  2. 在当前调用中传递的 FM 参数上使用 MD5 哈希在每次运行中创建唯一 ID

是否有唯一标识 RFC 调用的标准方法?也许某个SY领域?

PS在这个评论这里他们说(很明显)每次通话后关闭连接会比平时慢,所以这是不可取的。

4

1 回答 1

2

评论中的想法很有用,但在我的情况下无法实现。

是的,我可以生成 GUID,但问题在于将内存读/写到同一个 ID 的方式。将值写入内存的包含模块位于调用堆栈的深处,并且 READ 是在 RFC FM 主体中进行的,因此要从相同的内存 ID 读取/写入值,我应该传递在 RFC 生成的 GUID入口点(调用堆栈的根级别)到调用堆栈的第 10 层嵌套,这显然是不可能的,或者至少我没有找到方法。

这就是我解决问题的方法。我找到了一个完全符合我需要的 FM

 CALL FUNCTION 'TH_GET_SESSION_ID'
    IMPORTING
     session_id = id.

我用外部调用运行了一些测试,可以确认 FM 生成的 ID 在整个 RFC 调用中是持久的,但在调用之间是不同的。

于 2020-07-29T07:24:07.650 回答