Skip to Content
Technical Articles

Locking the GUI apps from the Fiori/UI5 has never been so easier (via the Durable Locks for ABAP programming model for Fiori)

Hi Everyone,

 

This blog is about understanding how the durable locks works in the new ABAP programming model for Fiori in creating the pessimistic locking for the Fiori apps which will also lock the GUI application.

I’ve seen people (including myself) struggling to answer the customers when they talk about pessimistic locking in Fiori apps as SAP officially given only ETAG functionality is optimistic based locking. But not anymore thanks to the durable locks which will create pessimistic locking for Fiori and GUI apps together at a time.

Please check the below blog about the locking mechanisms available for the UI5 apps and why the durable locks are introduced.

Note: Below blog talks about overriding the durable locks and processing locks in the second part, so you can skip that part and come here to see how the locking works without going in depth technically as it might be a bit confusing :).

Locking in S4HANA via the Durable Locks & CDS View ObjectModel.Lifecycle annotation

 

Overview:

Durable locks are long lasting locks because they don’t depend on the session/commit work. They depend on the context and will persist for a longer time(based on the configured expiry time). So what is this new context I just mentioned??

From the SAP Help link

A durable lock is requested using a context. A context is a lock phase in which durable locks are assigned to this context. A context belongs to a draft document and is bound to this draft or to a shorter lifespan.

Durable locks are only available for specific SAP applications or frameworks.

So the context is based on the draft document and like sap mentioned, these are only available for few frameworks and one such is ABAP Programming model for Fiori with draft and might probably for the RAP as well.

So for the people who are not very familiar to this framework, please check my other blog as the below example is based on it and If you try that example once, it will be very easy to understand the below process.

https://blogs.sap.com/2019/01/08/abap-programming-model-for-sap-fiori-draft-based-for-non-guid-keys-much-more..

 

Let’s see it in action

We will use the same example from the above blog.

Scenario: There will be two users DUSER1 and DUSER2 who will simultaneously open the sales order app and edit the same sales order entry in the Fiori launchpad.

Note: Till now we haven’t configured any locking here, they are auto implemented.

 

First DUSER1 opens the below salesorder and clicks on Edit button.

When clicked on the Edit button, a request will be sent to the backend and will create a draft document and from there onwards the user will work on the draft document and once saved, the data will be copied to the active document and draft will be deleted.

Along with the draft document, a lock will also be created in the SM12 this is called as the Durable lock. This will be auto created for the draft entry by the durable lock class which is part of APM framework. You can also notice that lock is not created for SO header key, it is only for the Draft entry.

 

Now when DUSER2 opens the same application then he will see the status that it is locked by ‘DUSER1’.

If the DURER2 opens the SO and edits it, he will get the below error as the lock still exists in SM12.

 

So till now we have seen how the locking works for the normal draft entry. If you observe, there is no lock created for the SO header key, it is only created for the draft entry in the SM12.

Now what will happen if there is a legacy GUI app which is still being used? Or If any interface calls comes from outside the SAP system and tries to update or delete the entry in the SAP system.

So somehow both the Draft entry locking and active entry locking should be linked right as in some cases user might lock the active entry from Fiori app and maybe some interface calls or gui app or some background job or some other process might try to update the same entry in the meantime.

For this SAP made it so easy, we just need to create or use an existing lock object and call it in the action(which is also auto created by SAP when the BOPF object is created). So simple right? Let’s do it then.

 

Go to the Lock class and in the below method, implement the locking

METHOD /bobf/if_lib_lock_active~lock_active_entity.

    DATA: lt_root        TYPE ztisalesordersheadtp,
          ls_root        LIKE LINE OF lt_root,
          lv_lock_failed TYPE abap_bool,
          ls_failed_key  TYPE /bobf/s_frw_key.

    io_read->retrieve(
      EXPORTING
        iv_node                 = is_ctx-node_key
        it_key                  = it_key
      IMPORTING
        et_data                 = lt_root
        et_failed_key           = et_failed_key
    ).

    READ TABLE lt_root INTO ls_root INDEX 1.
    IF sy-subrc EQ 0.
      CALL FUNCTION 'ENQUEUE_EZSOHEADLOCK'
        EXPORTING
          mode_zso_head  = 'E'
          salesorder     = ls_root-salesorder                 " 02th enqueue argument
          x_salesorder   = space            " Fill argument 02 with initial value?
          _scope         = '2'
          _wait          = space
          _collect       = ' '              " Initially only collect lock
        EXCEPTIONS
          foreign_lock   = 1                " Object already locked
          system_failure = 2                " Internal error from enqueue server
          OTHERS         = 3.
      IF sy-subrc <> 0.
        ls_failed_key-key = ls_root-salesorder.
        APPEND ls_failed_key TO et_failed_key.
      ENDIF.
    ENDIF.

  ENDMETHOD.

So for our legacy applications and for the active document, the locking is implemented. Let’s go back to the fiori app and click on cancel button, which will deletes the draft and removes the lock on the draft entry.

Now again open the sales order and click on edit button, which will create the draft document and along with it creates the lock entry for the draft document and now for the active document as well. Lets check the SM12 lock

We can see two locks are created, one for the draft entry and one for the active entry but both are linked with the draft document. But we never passed any draft document to the ENQUEUE object then how it automatically passes the draft id to it.

There is a class which will first sets the enqueue context and any enqueue object lock that is created afterwards will have the draft id attached to it. I couldn’t find it in the ABAP code, it might be that they are setting the draft id to the active entry lock at the kernal level.

Below is the code where the enqueue context is created for the draft document and will be attached to any lock that is created in that session. Even if you call BU_PARTNER enqueue FM, the BU Partner lock will be linked with the SO_HEAD Draft ID. But yeah, it is pretty useful in case if you want to lock any depended objects when the draft entry is created in the Fiori app.

Just to test if the locking works in the GUI, I created the below report program

Locking code from GUI application:

PARAMETERS:
  p_so TYPE zso_head-salesorder.

AT SELECTION-SCREEN.
  CALL FUNCTION 'ENQUEUE_EZSOHEADLOCK'
    EXPORTING
      salesorder     = p_so                 " 02th enqueue argument
    EXCEPTIONS
      foreign_lock   = 1                " Object already locked
      system_failure = 2                " Internal error from enqueue server
      OTHERS         = 3.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.


END-OF-SELECTION.
  WRITE: 'Locked Successfully'.

Now when we execute it, we will get the lock error.

Similarly if we lock is successfully obtained for the Sales order in the GUI app then in the Fiori app we will get the error.

 

BTW if the user creates the draft entry and doesn’t perform any action on it, after 15 min the locks will be auto removed by the framework and if you want to override this behavior or to know how it works then check out the below blog in the section “How the Durable locks works”.

https://blogs.sap.com/2019/01/09/abap-programming-model-for-sap-fioridraft-durable-locks-cds-view-objectmodel.lifecycle-annotation/

 

Let me know if you have any queries regarding this. I am also exploring this new programming model so any tips, corrections or suggestions are much appreciated.

 

Thanks,

Mahesh

9 Comments
You must be Logged on to comment or reply to a post.
  • Thanks, Mahesh. Very useful.

    And without your code. If first user starts edit “so_header” from gui and second from Fiori (same record)? What happen?

    • Hi Alexander, Thanks for the comment.

      I didn’t test this scenario and I will test and update you. But I can tell you from the code that I’ve seen in the backend that If you mention the annotation “ObjectModel.entityChangeStateId”  for lastChangedAt field (timestamp) then the optimistic error handling will gets triggered.

      Once the Optimistic handling is triggered, it will check the timestamp for the draft entry and the active entry. As the user changes it from the backend, etag check will fail and it will not allow the user to change the data in the UI.

      Anyways I will check and update you once. Thanks Again !!!

      BR,

      Mahesh

        • No, GUI will not check, If you look closely it doesn’t need to handle it. Let’s see this example.

          If the user clicks on edit , it will create a draft entry for the active entry and the etag for the draft entry will be the ‘lastChagedBy’ or some timestamp of the active entry.

          Now if the user goes and edit the backend, it will update the active entry data along with the timestamp. Now the other user clicks on save in the UI then the the draftframework will check if the timestamp for the draft and active is changed and it will stop the save from the UI.

           

          You have a valid question but if we think in real time uses case, we will always call the enqueue fm to lock the active entry (we have to) as that is the best practice in normal GUI or in the Draft based apps.

           

          BR,

          Mahesh

  • Thanks, Mahesh.

    And if I lock the Sales Order from UI5,  how to unlock the durable lock of the Sales Order from UI5.

    Because I used the BAPI tries to lock the Sales Order again which will cause the BAPI to fail.

    • If you delete the draft from the ui5 app, then the durable lock will be automatically deleted, which is the only option. Or you need to wait for the draft to get expired.

      • Mahesh, Thank you for your answer.

         

        I did some practice with reference to this series of blogs.

        Creating a draft enabled Sales Order Fiori App using the new ABAP Programming Model

        https://blogs.sap.com/2019/03/11/creating-a-draft-enabled-sales-order-fiori-app-using-the-new-abap-programming-model-part-1-overview/

         

        But in part 6, the author told me that the durable locking needs to be disabled which Implemented at part 4. If I don’t disable the durable lock, I can’ t update the draft to an active instance.

        So there’s no other way to solve this problem, right? Except delete the code of lock which implement at part 4.

         

         

        • Ideally it shoudn’t cause any issue.. Unless if the lock is being set in the update task..

          If the lock is set it will automatically get the draft context, atleast at the locking class, not sure if the context is passed to lock at the time of draft to active method.

          Did you try this and got an error at the time of draft delete?

          BR,

          Mahesh