abapcommitsaprfc

How to update a single database table in a separate LUW in ABAP?


I have a requirement in an existing production development to log errors. It needs to be done in multiple applications.

I created a table and called it in a method. I am calling a Function Module as starting new task to commit work.

This is done to avoid commit work in the actual application. However, in a test program I created I noticed that the system automatically calls commit work instantly when this FM is called.

In the code below, I expect 'Function Module' to be committed in the table, but it commits both 'Prog' and 'Function Module'. 'Prog' is committed instantly when the FM is called and 'Function Module' after commit work in the FM.

What other alternatives do I have? I have tried in update, background task, submit program, perform on commit. Nothing worked.

Main program:

REPORT zak_test_luw.
DATA: ls_log TYPE zdt_error_log,
      lv_tms TYPE timestampl.
    
GET TIME STAMP FIELD lv_tms.
ls_log-time_stamp = lv_tms.
ls_log-msg1 = 'prog'.
ls_log-msg2 = ''.
MOVE-CORRESPONDING sy TO ls_log.
MODIFY zdt_error_log FROM ls_log.
zdcl_utility_new=>update_logging_table( iv_msg1 = |Function Module| ).

Method:

METHOD update_logging_table.
    DATA: ls_log TYPE zdt_error_log,
          lv_tms TYPE timestampl.

    GET TIME STAMP FIELD lv_tms.
    ls_log-time_stamp = lv_tms.
    ls_log-msg1 = iv_msg1.
    ls_log-msg2 = iv_msg2.
    MOVE-CORRESPONDING sy TO ls_log.
    IF commit_work = abap_true.
      MODIFY zdt_error_log FROM ls_log.
      COMMIT WORK.
    ELSE.
      CALL FUNCTION 'ZDF_UPDATE_ERROR_LOG_TBL' STARTING NEW TASK 'LOGTABLE  '
        EXPORTING
          is_log = ls_log.
    ENDIF.
ENDMETHOD.

Function module:

FUNCTION zdf_update_error_log_tbl.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(IS_LOG) TYPE  ZDT_ERROR_LOG
*"----------------------------------------------------------------------

  MODIFY zdt_error_log FROM is_log.
  COMMIT WORK.

ENDFUNCTION.

Solution

  • in background task and in update task don't commit themselfs, but they only run when the calling program commits. That means you'd lose your log when there's a rollback. Perform on rollback also doesn't help, since you can't commit there, so you can't write to a database.

    As far as I know, the only way to run an independen routine without commiting is raising an event (BP_EVENT_RAISE) to run a job. You can save the log to a shared buffer and pass an id to read the buffer via the job parameter (I haven't verified this myself, but I'm pretty sure export to shared buffer doesn't need a commit and the ABAP-documentation also doesn't mention it).