В программе ABAP я заметил неожиданное сохранение данных при отображении локальной таблицы с использованием класса cl_salv_table
.
Для воспроизведения я создал минимальный пример кода. Программа выполняет вставку, отображает данные в формате ALV, затем выполняет ROLLBACK WORK
.
Я ожидаю, что вставленное значение будет присутствовать в базе данных ДО отката, и отсутствует ПОСЛЕ отката.
Однако, если между вставкой и откатом отображается сетка ALV, данные сохраняются после отката и сразу же видны другим транзакциям.
Это ожидаемое поведение, и если так, как я могу избежать этого? Мы используем этот класс довольно часто, и похоже, что мы можем непреднамеренно зафиксировать значения в базе данных, когда на самом деле этого не хотим.
Это код:
*&---------------------------------------------------------------------*
*& Report zok_alv_commit
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zok_alv_commit.
SELECTION-SCREEN BEGIN OF BLOCK b1.
PARAMETERS: p_showtb TYPE boolean AS CHECKBOX DEFAULT abap_false.
SELECTION-SCREEN END OF BLOCK b1.
START-OF-SELECTION.
DATA: lt_table TYPE TABLE OF zok_alv,
ls_table TYPE zok_alv.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Create new GUID and insert into table
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
TRY.
ls_table-guid = cl_system_uuid=>create_uuid_c22_static( ).
CATCH cx_uuid_error.
" Error creating UUID
MESSAGE e836(/basf/dps3_apodata).
ENDTRY.
WRITE: |Create guid { ls_table-guid } |, /.
INSERT zok_alv FROM ls_table.
APPEND ls_table TO lt_table.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" The important bit: show something in an ALV
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
IF p_showtb = abap_true.
cl_salv_table=>factory(
IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = lt_table
).
lo_alv->display( ).
ENDIF.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Check existence in table before and after rollback
" Expectation: If the ALV is shown above, the data is already committed,
" so the ROLLBACK WORK will not have an effect.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
SELECT SINGLE guid FROM zok_alv INTO @DATA(lv_ignored) WHERE guid = @ls_table-guid.
IF sy-subrc = 0.
WRITE: 'GUID exists on DB before rollback.', /.
ELSE.
WRITE: 'GUID does NOT exist on DB before rollback.', /.
ENDIF.
ROLLBACK WORK.
SELECT SINGLE guid FROM zok_alv INTO @lv_ignored WHERE guid = @ls_table-guid.
IF sy-subrc = 0.
WRITE: 'GUID exists on DB after rollback.', /.
ELSE.
WRITE: 'GUID does NOT exist on DB after rollback.', /.
ENDIF.
Требуется таблица ZOK_ALV
с только MANDT
и 22-символьным полем GUID
в качестве первичного ключа, ничего больше.
При выполнении кода с p_showtb
не проверено :
Как видите, значение отсутствует после отката и не отображается в таблице - как ожидалось.
При выполнении кода с p_showtb
проверено :
На этом этапе идентификатор SE16 уже виден в другом сеансе:
(я оставляю экран ALV с Back (F3)
на этом этапе)
Код подтверждает, что значение сохраняется, даже после отката:
Даже после выхода из программы значения сохраняются в БД.