目录
目的地设置
出站队列的目的地必须在事务 SM59中维护,并表示出站 bgRFC 类型 t 和类型 q 的执行目的地。入站队列的目的地必须在事务 SBGRFCMAINIDST 中维护。如果目的地无效,则抛出异常 CX_BGRFC_INVALID_DESTINATION。
出站事务bgRFC代码示例
DATA: my_destination TYPE REF TO if_bgrfc_destination_outbound,
my_unit TYPE REF TO if_trfc_unit_outbound,
dest_name TYPE bgrfc_dest_name_outbound.
DATA: text TYPE text200.
TRY.
dest_name = 'LOCALTEST'.
my_destination = cl_bgrfc_destination_outbound=>create( dest_name ).
my_unit = my_destination->create_trfc_unit( ).
text = 'Simple Outbound'.
CALL FUNCTION 'YLC_FUNC001' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC002' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC003' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC004' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC005' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
COMMIT WORK.
WRITE:/ 'Success'.
CATCH cx_bgrfc_invalid_destination .
WRITE:/ 'Error'.
ENDTRY.
以一个LUW进行提交,RFC中不能使用COMMIT WORK,ROLLBACK WORK
出站队列bgRFC代码示例
队列bgRFC队列名称只能字母数字和_/ ( [A-Z/][A-Z0-9_/]* )
DATA: my_destination TYPE REF TO if_bgrfc_destination_outbound,
my_unit TYPE REF TO if_qrfc_unit_outbound,
dest_name TYPE bgrfc_dest_name_outbound,
queue_name TYPE qrfc_queue_name,
queue_names TYPE qrfc_queue_name_tab.
DATA: text TYPE text200.
TRY.
dest_name = 'LOCALTEST'.
my_destination = cl_bgrfc_destination_outbound=>create( dest_name ).
my_unit = my_destination->create_qrfc_unit( ).
text = 'Simple Outbound - bgRFC type Q'.
CALL FUNCTION 'YLC_FUNC001' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC002' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC003' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC004' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC005' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
my_unit->add_queue_name_outbound( 'TEST_FUN1' ).
queue_name = 'TEST_FUN2'.
INSERT queue_name INTO TABLE queue_names.
my_unit->add_queue_names_outbound( queue_names ).
COMMIT WORK.
WRITE:/ 'Success'.
CATCH cx_bgrfc_invalid_destination .
WRITE:/ 'Error'.
CATCH cx_qrfc_invalid_queue_name .
WRITE:/ 'Error'.
CATCH cx_qrfc_duplicate_queue_name.
WRITE:/ 'Error'.
ENDTRY.
入站和出站队列bgRFC代码示例
DATA: my_destination TYPE REF TO if_bgrfc_destination_outbound,
my_unit TYPE REF TO if_qrfc_unit_outinbound,
dest_name TYPE bgrfc_dest_name_outbound,
queue_name TYPE qrfc_queue_name,
queue_names TYPE qrfc_queue_name_tab.
DATA: text TYPE text200.
TRY.
dest_name = 'LOCALTEST'.
my_destination = cl_bgrfc_destination_outbound=>create( dest_name ).
my_unit = my_destination->create_qrfc_unit_outinbound( ).
text = 'Simple Outbound - bgRFC type Q'.
CALL FUNCTION 'YLC_FUNC001' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC002' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC003' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC004' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC005' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
queue_name = 'TEST_FUN1'.
INSERT queue_name INTO TABLE queue_names.
my_unit->add_queue_names_outbound( queue_names = queue_names ignore_duplicates = abap_true ).
my_unit->add_queue_names_inbound( queue_names = queue_names ignore_duplicates = abap_true ).
COMMIT WORK.
WRITE:/ 'Success'.
CATCH cx_bgrfc_invalid_destination .
WRITE:/ 'Error'.
CATCH cx_qrfc_invalid_queue_name .
WRITE:/ 'Error'.
ENDTRY.
入站事务bgRFC代码示例
DATA: my_destination TYPE REF TO if_bgrfc_destination_inbound,
my_unit TYPE REF TO if_trfc_unit_inbound,
dest_name TYPE bgrfc_dest_name_inbound.
DATA: text TYPE text200.
TRY.
dest_name = 'BGINBOUND'.
my_destination = cl_bgrfc_destination_inbound=>create( dest_name ).
my_unit = my_destination->create_trfc_unit( ).
text = 'Simple inbound bgRFC type T'.
CALL FUNCTION 'YLC_FUNC001' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC002' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC003' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC004' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC005' IN BACKGROUND UNIT my_unit
EXPORTING
text = text.
COMMIT WORK.
WRITE:/ 'Success'.
CATCH cx_bgrfc_invalid_destination .
WRITE:/ 'Error'.
ENDTRY.
出站队列bgRFC队列单元交叉场景示例
DATA: my_destination TYPE REF TO if_bgrfc_destination_outbound,
my_unit1 TYPE REF TO if_qrfc_unit_outbound,
my_unit2 TYPE REF TO if_qrfc_unit_outbound,
dest_name TYPE bgrfc_dest_name_outbound,
queue_name TYPE qrfc_queue_name,
queue_names TYPE qrfc_queue_name_tab.
DATA: text TYPE text200.
TRY.
dest_name = 'LOCALTEST'.
my_destination = cl_bgrfc_destination_outbound=>create( dest_name ).
my_unit1 = my_destination->create_qrfc_unit( ).
my_unit2 = my_destination->create_qrfc_unit( ).
text = 'Simple Outbound - bgRFC type Q multiple'.
CALL FUNCTION 'YLC_FUNC001' IN BACKGROUND UNIT my_unit1
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC002' IN BACKGROUND UNIT my_unit1
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC003' IN BACKGROUND UNIT my_unit2
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC004' IN BACKGROUND UNIT my_unit2
EXPORTING
text = text.
CALL FUNCTION 'YLC_FUNC005' IN BACKGROUND UNIT my_unit2
EXPORTING
text = text.
queue_name = 'TEST_FUN2'.
INSERT queue_name INTO TABLE queue_names.
my_unit2->add_queue_names_outbound( queue_names ).
my_unit1->add_queue_name_outbound( 'TEST_FUN1' ).
my_unit2->add_queue_name_outbound( 'TEST_FUN1' ).
COMMIT WORK.
WRITE:/ 'Success'.
CATCH cx_bgrfc_invalid_destination .
WRITE:/ 'Error'.
CATCH cx_qrfc_invalid_queue_name .
WRITE:/ 'Error'.
CATCH cx_qrfc_duplicate_queue_name.
WRITE:/ 'Error'.
ENDTRY.
由于单元1和单元2均在队列1中,因此队列2需要等待单元1执行结束
反之,先单元2再单元1,队列2不会等待队列1
开发API
类 CL_QRFC_LOCK_INBOUND、CL_QRFC_LOCK_OUTBOUND 和 CL_QRFC_LOCK_NOSEND,您可以使用队列锁来阻止处理单元,也可以取消队列锁。
LOCK_QUEUE_FROM_TOP 方法将第一个单元锁定在目标指定队列的开头。这使得追溯锁定队列成为可能。如果不存在任何单元,则会自动创建一个空单元来映射锁。
LOCK_QUEUE_FROM_CURRENT_POS 方法锁定下一个单元的执行(指提交的单元),该单元被写入目标的指定队列。这使得抢先锁定队列成为可能。创建一个空单元来映射锁。
所有队列锁在下一次 COMMIT WORK 时变为活动状态。如果在应用程序 LUW 中同时创建了单元锁和队列锁,则始终首先设置队列锁,然后将单元锁分配给适当的队列。
DATA lock_id TYPE bgrfc_lock_id.
lock_id = my_unit->delay( 30 ).
lock_id = my_unit->lock( ).
GET_UNIT_STATE返回后台单元状态
GET_QUEUE_STATE查询 qRFC 单元的队列状态
DATA(lv_unit_id) = cl_bgrfc_server=>get_unit_id( ).
异常
例外 | 原因 |
CX_QRFC_DUPLICATE_LOCK | 后台 RFC 中的重复锁定 |
CX_QRFC_DUPLICATE_QUEUE_NAME | qRFC 中一个单元的重复队列名称 |
CX_QRFC_INVALID_QUEUE_NAME | 队列名称无效 |
CX_BGRFC_INVALID_DESTINATION | 后台 RFC 中的目标错误 |
CX_BGRFC_INVALID_UNIT | 后台 RFC 单位无效 |
CX_QRFC_NO_FAILED_UNIT | 队列不包含任何不正确的单位 |
CX_QRFC_NO_SINGLE_QUEUE_NAME | 只允许使用一个队列名称 |
CX_BGRFC_WRONG_EXEC_CONTEXT | 该函数无法在当前上下文中运行 |
CX_BGRFC_ILLEGAL_PERMUTATION | 无效排列 |
CX_BGRFC_INVALID_RETRY_KEY | 重试原因无效 |
CX_BGRFC_INVALID_TIME_SPEC | 无效的日期规范 |
CX_QRFC_NO_QUEUE_NAME | 缺少队列名称 |
my_unit->if_bgrfc_unit~unit_id.
DATA(lv_state) = cl_trfc_client_inbound=>if_bgrfc_client~get_unit_state( lv_unit_id ).
IF lv_state = if_bgrfc_client=>unit_state_runnable OR
lv_state = if_bgrfc_client=>unit_state_retry OR
lv_state = if_bgrfc_client=>unit_state_in_execution.
ENDIF.
COMMIT WORK语句之后,一个单元被耗尽 。可以实现方法 CREATE_UNIT_BY_PATTERN以再次使用该单元。
SEPARATE_FROM_UPDATE_TASK方法 删除单元处理和更新记录之间的绑定。
bgRFC监控管理
修复错误后重启错误单元
bgRFC调试
报错队列会锁定,解锁后再重启错误单元
注意事项
RFC中不允许 WAIT, COMMIT WORK, ROLLBACK WORK语句,以及HTTP communication (using the class CL_HTTP_CLIENT) 和函数DB_COMMIT 的调用,可以使用MESSAGE进行干涉
一个单元中的数据库操作,会在执行完后在数据库中持久化,如果此时出现错误消息,整个单元不能再次一起回滚。
每个单元可以有任意数量的锁。一个单元只有在所有锁都被删除后才能被处理。每个锁由一个唯一的 lock_id表示. 只能释放自己的锁,其他程序的运行时行为不会受到过早释放锁的影响。
https://blog.csdn.net/xiefireworks/article/details/126294866