每个 RFC 调用的唯一 ID
Unique ID for every RFC call
我在外部调用一些 RFC 模块,它调用其他模块并在调用堆栈中计算一些值并将其保存到内存中,然后在最后读取该值并 returns 给外部调用者。每次计算可能不同,所以我们需要相应地读取内存区域。
本例并发症为:
- 模块总是从同一个系统调用,所以调用者总是相同的
- 调用FM的用户相同,所以用户也始终相同
- 连接将被重用,正好 like described here,因此 ABAP 内存也将相同
我们的想法是使用仅对当前调用唯一的 ID 写入内存,而不是之前的调用,即内存中的值将始终相关。
让我用我创建的这个简单的 FM 来说明这个案例。该模块将 return 只有在当前调用中设置的值,即只有相关的一个。
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
...
>>>
因此,内存按预期重用,所有进一步的 运行 可能会消耗错误的值。
我在这里看到的可能的解决方案:
- 设置JCo客户端每次关闭RFC连接,这样每次都会创建新的ABAP内存区域
- 在当前调用中传递的 FM 参数上使用 MD5 哈希在每个 运行 中创建唯一 ID
是否有一种标准方法来唯一标识 RFC 调用?也许一些 SY
字段?
P.S。 In this comment and here 他们说(很明显)每次调用后关闭连接会比平时慢,所以这是不可取的。
评论中的想法很有用,但对我而言无法实现。
是的,我可以生成 GUID,但问题在于 reading/writing 内存到相同 ID 的方式。
将值写入内存的包含模块位于调用堆栈的深处,读取是在 RFC FM 主体中进行的,因此对于 read/write 来自同一内存 ID 的值,我应该传递生成的 GUID RFC 入口点(调用堆栈的根级别)到调用堆栈的第 10 层嵌套级别,这显然是不可能的,或者至少我没有找到方法。
我就是这样解决问题的。我找到了一个完全符合我需要的 FM
CALL FUNCTION 'TH_GET_SESSION_ID'
IMPORTING
session_id = id.
我运行一些外部调用测试,可以确认FM生成的ID在整个RFC调用中是持久的,但调用之间不同。
SY-MODNO
的值可用于跟踪 SUBMIT
的程序。
https://answers.sap.com/questions/627157/how-could-i-create-unique-memory-id.html
我在外部调用一些 RFC 模块,它调用其他模块并在调用堆栈中计算一些值并将其保存到内存中,然后在最后读取该值并 returns 给外部调用者。每次计算可能不同,所以我们需要相应地读取内存区域。
本例并发症为:
- 模块总是从同一个系统调用,所以调用者总是相同的
- 调用FM的用户相同,所以用户也始终相同
- 连接将被重用,正好 like described here,因此 ABAP 内存也将相同
我们的想法是使用仅对当前调用唯一的 ID 写入内存,而不是之前的调用,即内存中的值将始终相关。
让我用我创建的这个简单的 FM 来说明这个案例。该模块将 return 只有在当前调用中设置的值,即只有相关的一个。
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
...
>>>
因此,内存按预期重用,所有进一步的 运行 可能会消耗错误的值。
我在这里看到的可能的解决方案:
- 设置JCo客户端每次关闭RFC连接,这样每次都会创建新的ABAP内存区域
- 在当前调用中传递的 FM 参数上使用 MD5 哈希在每个 运行 中创建唯一 ID
是否有一种标准方法来唯一标识 RFC 调用?也许一些 SY
字段?
P.S。 In this comment and here 他们说(很明显)每次调用后关闭连接会比平时慢,所以这是不可取的。
评论中的想法很有用,但对我而言无法实现。
是的,我可以生成 GUID,但问题在于 reading/writing 内存到相同 ID 的方式。 将值写入内存的包含模块位于调用堆栈的深处,读取是在 RFC FM 主体中进行的,因此对于 read/write 来自同一内存 ID 的值,我应该传递生成的 GUID RFC 入口点(调用堆栈的根级别)到调用堆栈的第 10 层嵌套级别,这显然是不可能的,或者至少我没有找到方法。
我就是这样解决问题的。我找到了一个完全符合我需要的 FM
CALL FUNCTION 'TH_GET_SESSION_ID'
IMPORTING
session_id = id.
我运行一些外部调用测试,可以确认FM生成的ID在整个RFC调用中是持久的,但调用之间不同。
SY-MODNO
的值可用于跟踪 SUBMIT
的程序。
https://answers.sap.com/questions/627157/how-could-i-create-unique-memory-id.html