Skip to Content
Technical Articles
Author's profile photo Renzo Colle

The SAP LUW in ABAP Cloud

Preface

This blog describes the differences between classic ABAP programming and ABAP Cloud programming with regards to the SAP Logical Unit of Work (SAP LUW) [1] and the ABAP RESTful application programming model (RAP). It helps to understand how database updates work and what developers must consider avoiding data inconsistencies during database updates.

Classic ABAP Programming

In typical business applications, the data is changed, further changes are derived, and the data is verified. If the resulting state based on these changes is consistent from an application point of view, the changes are finally committed to the database. All changes made are committed with one atomic database transaction following the ACID [2] paradigm.

To achieve this, SAP provides the SAP Logical Unit of Work (SAP LUW) for classic ABAP programming. As the database is the central resource and can become a bottleneck, the processing and handling is done on the ABAP application server. Therefore, the data changes are not directly written to the database but kept in local temporary tables or buffers and are then jointly written to the database, either directly or via SAP update task. The SAP LUW terminates by calling COMMIT WORK if all changes were done successfully, or by calling ROLLBACK WORK if not.

Processing the COMMIT WORK statement includes:

  • the update task processing.
  • a database commit of the primary database connection.
  • starting of further asynchronous processing (e.g., via background RFCs) or registering on the transaction end events to clean up the buffers and prepare for the next SAP LUW in the same ABAP session.

When a ROLLBACK WORK statement is processed all changes are discarded, the current SAP LUW is terminated and a new one is opened.

Why is there an Update Task in classic ABAP programming?

The recommendation for classic ABAP programming is to always use update task function modules to perform modifying database operations, due to mainly three reasons:

  • In the past, database updates had a significant impact on the end-user performance. The update task offered an option to perform the (real) actual database changes asynchronously. This helped improving the perceived end-user performance.
  • Data consistency was not always given because proper isolation of database modifications was not available for all databases supported by SAP at that time. This means, that uncommitted database modifications were visible to other transactions although not finally committed.[3]
  • The SAP LUW is confirmed with an explicit COMMIT WORK But, as will be explained in the next section, the ABAP Platform sometimes invokes implicit database commits on the primary database connection. If data was already written before to the database, then the implicit database commit would result in multiple database transactions (database LUW) within one SAP LUW which violates the ACID paradigm.

Why are there implicit database commits?

The ABAP Platform scales via load balancing and multiple application server instances. In the cloud, these can be added and removed on demand. The number of work processes of an ABAP application server is limited, and their usage optimized. If a work process needs to wait (idle), e.g., when waiting for user interaction or remote connection, the work process is released for a different workload. This is done by saving (also called rolling-out) the current workload context and releasing the resources. This approach requires a database commit. It also explains why a synchronous RFC (sRFC), calling a WAIT statement (e.g., for asynchronous tasks via asynchronous RFC (aRFC)) or the invocation of an HTTP request via HTTP client leads to a database commit – as it might take a while until these requests return and the program can continue, and it is usually not known upfront how long it takes.

What about secondary database connections?

Database modifications and commits – on service connections or via secondary database connections – are allowed within the SAP LUW. These connections are usually used by technical components, e.g., for fetching the next bunch of numbers of a buffered number range, or for persistent caches, traces, logs or similar.

ABAP Cloud Development Model

In the ABAP Cloud development model, the classic update task is not offered anymore. The reasons for the usage of an update task, as mentioned in the chapter before, are not applicable anymore:

  • Writing directly to the database tables is no bottleneck anymore, as database processing on SAP HANA is much faster.
  • SAPĀ HANA as the only supported database provides full isolation, thus preventing dirty read.
  • Implicit database commits are no issue anymore if database modifications are triggered as late as possible, ensuring that afterwards no database commit except via COMMIT WORK is invoked.

Nevertheless, data changes are still done in the buffers of the application server. The data is enriched, verified, and finally saved to the database.

It cannot be prevented that implicit database commits happen before saving the data to the database, as calling remote services (e.g., via sRFC or HTTP client) is still possible. Consequently, modifying database operations are only allowed at the end of the SAP LUW.

Furthermore, once the end of the SAP LUW is reached and the modifying database operations are invoked, all operations that lead to an implicit database commit are not allowed anymore, as these would disrupt the consistency and atomicity (ACID).

Obviously, the explicit database commit on the primary database connection is only allowed to finally terminate the SAP LUW, but not before. Also, the pattern to start further asynchronous processing is still needed and valid (e.g., via bgRFC).

This requires to strictly follow these rules from application development to avoid inconsistencies due to multiple database LUWs.

How is this handled in the ABAP RESTful Application Programming Model (RAP)?

Compared to classic ABAP programming, RAP is a more advanced application programming model with further abstraction. RAP controls the transactions (ABAP LUW) and provides an orchestration with clearly defined phases, namely:

  • the interaction phase,
  • the early-save phase,
  • the late-save phase followed by a cleanup.

The RAP transaction model is described in more detail in the RAP documentation
(The RAP Transactional Model for the SAP LUW).

Based on this transaction model, the rules, and guidelines of the SAP LUW can be manifested by runtime checks. With these checks in place, you can avoid data inconsistencies or race conditions.

The following violations will always lead to a runtime error in a RAP context:

  • Explicit use of COMMIT WORK or ROLLBACK WORK statements, as the transaction handling and database commit is exclusively handled by RAP.
  • Calling the update or background task (bgRFC) [4] in the interaction phase or early-save phase.

Some other operations only lead to runtime errors, if the RAP behavior definition is implemented in ABAP for Cloud Development and the strict(2)-mode [5] is applied:

  • Invoking authorization checks in the early-save or late-save phase.
  • Modifying database operations in the interaction phase or early-save phase.
  • Raising business events in the interaction phase or early-save phase.
  • (Implicit or explicit) database commits for the primary database connection in the late-save phase.

Conclusion

The ABAP RESTful Application Programming Model supports you in following the rules to avoid issues with transactional consistency caused by modifying statements or database commits in the wrong sequence / phase.

Feel free to share your feedback or thoughts by commenting this BLOG.

With the information provided here you also get an understanding on how and where BAPIs can be used in RAP as described in Using BAPIs in RAP provided by my colleague Marcel Hermanns.

Follow for more via Renzo Colle.

[1] A sequence of programming steps and data updates, whose database changes are updated within a single database commit.
[2] ACID (atomicity, consistency, isolation, durability), check also https://en.wikipedia.org/wiki/ACID.
[3] Also known as dirty read.
[4] Not available in ABAP Platform Cloud, work in progress.
[5] The strict mode adds additional consistency checks during development so that to the RAP behavior definition is developed life cycle stable.

Assigned Tags

      12 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo First Name Last Name
      First Name Last Name

      Nice. The only problem is that Restful ABAP (RAP) isn't restful anymore that way.

      Author's profile photo Renzo Colle
      Renzo Colle
      Blog Post Author

      Not sure I understand that comment. The BLOG describes the behavior of an atomic transaction (LUW) in ABAP, e.g. initiated by a single OData request / change set.

      Author's profile photo Sagar Prusty
      Sagar Prusty

      Renzo Colle This is very good concept. I have been working in RAP for last 1 year. I was wondering about the concepts for the update events and how it works. It is giving the clear understanding about RAP. Will keep in mind while working further.

      Author's profile photo Renzo Colle
      Renzo Colle
      Blog Post Author

      Hi Sagar, thanks for the feedback.

      Author's profile photo Sergio Ferrari
      Sergio Ferrari

      Thanks a lot Renzo Colle ! I believe this is a very relevant topic.

      It would also be interesting to know if there are differences in LUW when operating ABAP Cloud embedded in SAP S/4HANA on-prem or in SAP BTP.

      To me, it would be interesting exploring SAP LUW in mixed deployments (cloud/on-prem) and in mixed software architectures (e.g. RAP/non-RAP) because often present these days in real-life scenarios.

      Kind regards,

      Sergio

       

       

      Author's profile photo Renzo Colle
      Renzo Colle
      Blog Post Author

      Hi Sergio, thanks for the feedback.

      In fact there is no difference in embedded scenario or even on premise if you use "ABAP for Cloud Development" as ABAP language version. The difference is only if you switch to "Standard ABAP" which is not possible in SAP BTP, ABAP environment. In this case certain violations detected by RAP do not lead to a runtime error, but are just logged for analysis. Further here also currently not available features in ABAP Cloud can be used, e.g. update task function modules or RFC functions. For these it is ensured similarly that they are only called in the correct phase.

      Thus, in mixed scenarios where also non-RAP parts are running the same rules are applied (and should have been even before), so RAP just makes them more visible.

      Author's profile photo Stephan Heinberg
      Stephan Heinberg

      Thanks, Renzo!

      Is it possible to cover these complex topics also within some DMO flight model samples? E.g. what Marcel pointed out: REPORTED and FAILED can also be filled in the late save, by using the save handler cl_abap_behavior_saver_failed

      Author's profile photo Renzo Colle
      Renzo Colle
      Blog Post Author

      Hi Stephan, thanks for the feedback.

      I will check with my colleagues if there is already a scenario in place or planned.

      Author's profile photo Sujin Appukuttan
      Sujin Appukuttan

      Thank you Renzo for elaborating the RAP LUW details. I have 2 questions after reading the blog:

      1) You mentioned "Writing directly to the database tables is no bottleneck anymore". Does this mean all the managed BO implementation utilize the direct DB modifications? And if yes, is this the guideline moving forward?

      2) You also mentioned "data changes are still done in buffers of app server". Is the buffer handling similar to what was used in BOPF framework? There the buffer handling was taken care by the framework. But here in the official unmanaged RAP example of /DMO/Flight, I see the buffers are mainly the abap internal tables/abap variables to store the data during interaction phase. So is it safe to assume a similar approach is happening internally in a managed scenario too or is there a separate buffer handling framework for managed scenario?

      Author's profile photo Renzo Colle
      Renzo Colle
      Blog Post Author

      Hi Sujin, thanks for the feedback. Here a short answer to your questions:

      1. Here I was referring to the classic update task where the data is first blobbed to the database and in a second work process (the update task) read again, then the update task function modules are called and write to the final database tables. As in Cloud as well as in RAP in general we always run in local update task the data is always directly written to the final database tables. So it does not really matter if you use an update task function module or not in this case. In ABAP for Cloud Development this is not only a guideline, but update task function modules are not allowed anymore.
      2. Yes, any transactional processing happens on the app server and the buffer is handled according to the RAP implementation type. This is the main aspect of it. So in MANAGED the RAP infrastructure handles CRUD and the transactional buffer, in BOPF MANGED this is done by BOPF and in UNMANAGED this is done by the application. Only in the late save phase the changes are collected (after all is verified) and written to the database (with or without update task function module).
      Author's profile photo Sujin Appukuttan
      Sujin Appukuttan

      Hi Renzo,

       

      Regarding the #2 - Thank you for confirming on the BOPF framework for managed use case.

      For unmanaged use case, is the recommended approach to implement buffer handling way its shown in the official example /DMO/FLIGHT_U where the interaction phase data is stored in the abap internal tablesĀ  and the later used by SAVE phase or can we use BOPF framework for unmanaged buffer handling too?

       

      Regards,

      Sujin

      Author's profile photo Renzo Colle
      Renzo Colle
      Blog Post Author

      For UNMANAGED the assumption is that there is already legacy functionality with transactional buffers and application logic. Therefore building a secondary buffer does not really make sense. In such a case it is better to use MANAGED and ensure interoperability with a still running legacy application (e.g. WebGUI or similar) via UNMANAGED LOCK, UNMANAGED SAVE / ADDITIONAL SAVE etc.