1. 背景
COMMIT WORK关键字的执行,意味着SAP LUW的提交,那么在ABAP代码中,如何判断COMMIT WORK注册的事务都已经执行完成呢?
2. 解决方案
针对这一场景,我们可以使用ABAP Object Services框架(CL_OS_SYSTEM)中提供的一个标准事件IF_OS_TRANSACTION~FINISHED
。
interface IF_OS_TRANSACTION
public .
events FINISHED
exporting
value(STATUS) type OS_TSTATUS optional .
...
endinterface.
这个事件的触发,意味着事务执行的完成。
看一个测试的小例子:
REPORT zos_event.
CLASS lcl_main DEFINITION.
PUBLIC SECTION.
CLASS-METHODS get_instance
RETURNING VALUE(ro_instance) TYPE REF TO lcl_main.
METHODS register_trans_finished_event.
PRIVATE SECTION.
CLASS-DATA so_instance TYPE REF TO lcl_main.
DATA mo_transaction TYPE REF TO if_os_transaction.
DATA mv_event_registered TYPE abap_bool.
METHODS handle_trans_finished_event
FOR EVENT finished OF if_os_transaction
IMPORTING !status.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD get_instance.
IF so_instance IS INITIAL.
so_instance = NEW #( ).
ENDIF.
ro_instance = so_instance.
ENDMETHOD.
METHOD handle_trans_finished_event.
BREAK-POINT.
ENDMETHOD.
METHOD register_trans_finished_event.
mo_transaction = cl_os_system=>get_transaction_manager( )->get_current_transaction( ).
SET HANDLER handle_trans_finished_event FOR mo_transaction ACTIVATION abap_true.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(lo_main) = lcl_main=>get_instance( ).
lo_main->register_trans_finished_event( ).
COMMIT WORK.
BREAK-POINT.
在程序中,我们定义了对于事件IF_OS_TRANSACTION~FINISHED
的响应方法,并在程序中开启对于此事件的监听。
...
mo_transaction = cl_os_system=>get_transaction_manager( )->get_current_transaction( ).
SET HANDLER handle_trans_finished_event FOR mo_transaction ACTIVATION abap_true.
...
运行程序,并开启调试器,我们可以看到,事件IF_OS_TRANSACTION~FINISHED
会在after_commit这个步骤触发。
这也意味着,这是事件触发的时间点,是在Commit Work完成之后。
3. 用途
对于这个事件的相应有什么用途呢?它其实提供给开发者一个响应的时间点,也即在提交的事务都已经执行执行结束后,可以有一些后续的操作。例如,写一些额外的系统日志,提交另外一个异步的任务等。
另外,如果提交的任务中有IN UPDATE TASK的任务,我们在调试器中也可以看到,这个FINISHED
的事件,其实会在所有的UPDATE TASK任务结束后触发。
这和我们的预期也是一致的。
4. 小结
本文介绍了ABAP代码中监控COMMIT WORK执行结束的一种方式,通过对于事件IF_OS_TRANSACTION~FINISHED
的响应,让我们有机会在执行完SAP LUW的事务后,进行一些后续的操作。