ABAP / FIELD NOTES

Why Is the Row Still Missing Right After COMMIT WORK?

The fictional key K-100, registered for the update task, can still be missing on the read right after COMMIT WORK. Without AND WAIT, sy-subrc 0 is not success, and an implicit commit, a rollback, and program end are different outcomes.

If the next line after COMMIT WORK reads the same key and the row is missing, first separate a change written directly in the dialog program from a change that was only registered for the update task. Registration does not insert the row on that line. Without AND WAIT, and when the update is not local, COMMIT WORK does not wait for the update work process to finish.

The key K-100 below is a fictional value used to follow that sequence. It was not executed or queried on a company system. The explanation is limited to the classic update task described in the ABAP keyword documentation. It does not establish that the RAP save sequence, or the same statement in ABAP Cloud, means the same thing. The statement's behavior is written in the ABAP keyword documentation for COMMIT WORK.

Why does the table stay unchanged after registration alone?

CALL FUNCTION ... IN UPDATE TASK registers an update function module for later execution. The module does not run on that line, and the row is not created there. Synchronous and asynchronous updates run in their own update sessions. Only a local update runs in a new internal session of the current work process. While an update is executing, forbidden statements are not allowed, and authorization checks are not performed.

The example is one high-priority module registered to write the key K-100. There has been no COMMIT WORK and no ROLLBACK WORK. The table has no K-100. A direct INSERT in the same program is a different request. That insert belongs to the database LUW that is open now. The update-task change is a registration record.

Diagram of the fictional key K-100 only registered for the update task. The dialog program uses IN UPDATE TASK to register the module for later, and the module does not run on that line. The registration is one high-priority module and the key K-100, not an execution record. The table has no row K-100, and this is not the same request as a direct INSERT.
Registration writes down K-100. It does not create the row on that line.

Why can the next read still be empty after COMMIT WORK alone?

COMMIT WORK closes the current SAP LUW and opens a new one. It starts processing of the update function modules registered until then. High-priority modules, called VB1 in the keyword documentation, run in registration order inside one database LUW. Without AND WAIT, and when the update is not local, the program does not wait until the update work process finishes those modules. It continues immediately after COMMIT WORK. The next SELECT can miss K-100. A missing row does not mean the registration never happened.

Without AND WAIT, COMMIT WORK always sets sy-subrc to 0. That 0 is not a report that the update succeeded. The value is still 0 at this point if the update fails later.

Low-priority modules are called VB2 in the documentation. After every high-priority module has succeeded, they run in registration order in their own shared database LUW. While an update function module is running, a database commit, a database rollback, and a change to update control are not allowed. Statements that would do those things cause runtime errors. COMMIT WORK inside an update module produces COMMIT_IN_POSTING.

COMMIT WORK also commits the database connections that are currently open. A change written directly in the dialog and a row the module will write later are not visible at the same moment. The direct change belongs to that database commit. A row such as K-100, handed to the module, is written when the module runs.

Diagram of the fictional case after COMMIT WORK without AND WAIT. The statement closes the SAP LUW and starts the registered modules, but the caller does not wait for the update work process. The next SELECT can still miss K-100, and that absence does not mean registration failed. Without AND WAIT, sy-subrc is always 0, and that 0 is not update success.
Without the wait, the next read can run before K-100 is written. sy-subrc 0 at that point is not a success report.

What does AND WAIT wait for, and what does sy-subrc say?

With AND WAIT, and when the update is not local, the program does not continue until the update work process has executed the high-priority modules. sy-subrc 0 means that update succeeded. sy-subrc 4 means it did not. Neither value means the low-priority modules have finished. The documentation places the end of the wait at execution of the high-priority modules.

In this fictional example, the module's job is to write K-100, so 0 is read as that write finishing inside the high-priority processing. If the value is 4, that processing did not succeed, and the next read should not be treated as proof that the row exists. That read was not executed for this article.

A local update has to be switched on with SET UPDATE TASK LOCAL before the module is registered. The keyword documentation's update example describes local updates as always performed synchronously. They then run in the current work process, not in a separate update work process. Using plain COMMIT WORK with local update left off, and checking the row on the next line, is a reading of the asynchronous path that does not wait.

If a runtime error occurs in an update, the update work process performs a database rollback, logs it in the corresponding database tables, and notifies the user who created the entries by SAPMail. The documentation says the canceled entries can be updated again after the cause is corrected. That repeat was not run here.

Diagram separating sy-subrc after COMMIT WORK AND WAIT. Zero means the high-priority modules succeeded, and the program does not continue until then. Four means those modules did not succeed, and this four is not returned without AND WAIT. Low-priority VB2 runs after high priority succeeds, in its own shared database LUW, and the AND WAIT wait does not extend to VB2.
Zero and four report the high-priority modules. They do not say whether the low-priority modules have finished.

Why do an implicit commit, a rollback, and program end finish differently?

A change of work process brings an implicit database commit. That happens when a classic dialog step ends. The keyword documentation's update example uses WAIT UP TO for the same kind of break. The example places WAIT UP TO between registrations and says the later COMMIT WORK executes the modules registered up to that point. An implicit database commit does not close the SAP LUW.

COMMIT CONNECTION and the function module DB_COMMIT are database commits as well. The keyword documentation distinguishes COMMIT WORK as the statement that also closes the current SAP LUW and performs the actions that go with it. A statement used only to make the database durable does not run the registered update modules in its place.

ROLLBACK WORK closes the current SAP LUW and cancels that LUW's change requests. It deletes modules registered with IN UPDATE TASK from the tables the documentation abbreviates as VB... The module that was going to write K-100 does not run. Registrations made with PERFORM ON COMMIT are deleted too, and subroutines registered with PERFORM ON ROLLBACK are executed.

If the program ends, or the internal session closes, and the SAP LUW ends without COMMIT WORK, the registered procedures are ignored. Registered update function modules remain on the database but can no longer be executed. A record that remains is not the same state as a registration that can still run.

COMMIT WORK inside a program called with CALL DIALOG is an exception. That statement does not start ON COMMIT subroutines or update function modules, and it does not close the current SAP LUW. The caller's COMMIT WORK can close that SAP LUW. The statement inside the dialog module still triggers a database commit. Reading every COMMIT WORK as the start of the update does not hold for this call.

Diagram comparing three endings of the same fictional registration for K-100. An implicit database commit at the end of a dialog step or at WAIT UP TO ends only the database LUW and leaves the registration. ROLLBACK WORK deletes the registration from VB... so the module does not run. If the program or internal session ends without COMMIT WORK, the registered procedures are ignored and the record remains but can no longer be executed.
An implicit commit leaves the registration, a rollback deletes it, and ending without a commit leaves a record that can no longer run.

When the next read is empty, write down four questions first.

  • Was the change an IN UPDATE TASK registration, or was it written directly in the dialog?
  • Did COMMIT WORK include AND WAIT, and was a local update switched on before registration?
  • Was there a ROLLBACK WORK before the read, or did the session end without COMMIT WORK?
  • If sy-subrc 0 was read as success, was AND WAIT actually present?

A missing number is a different question. A gap from main-memory number-range buffering is not the same record as the update registration described here. When K-100 is absent, separate whether the module has not run yet, whether the registration was deleted, or whether the record remains but can no longer be executed, before treating the row as deleted.

END OF NOTEBack to the library
COMMENTS BOX

Add your perspective.

Share a question, another approach, or something you have tried.

Newest first

Checking sign-in…

Loading comments…