Skip to Content
Technical Articles
Author's profile photo Amy King

Code Snippet Series: Wait a Fraction of a Second

This post is part of a series on code snippets. The complete list of posts in the series is available in the document Code Snippets: A Blog Series.

I occasionally need to wait for a lock entry to be dequeued when I have a multi-step scenario where COMMIT WORK AND WAIT is insufficient but waiting a static number of seconds with WAIT UP TO n SECONDS could result in waiting longer than necessary.

With the below code, I reduce wait time to the shortest possible wait–depending on use, even down to one tenth of a second.

DATA lt_enq TYPE STANDARD TABLE OF seqg3.

DATA: BEGIN OF ls_time,
        start   TYPE timestampl,
        now     TYPE timestampl,
        elapsed TYPE tzntstmpl, " in seconds
        limit   TYPE tzntstmpl VALUE 3, " in seconds
      END OF ls_time.

GET TIME STAMP FIELD ls_time-start.

WHILE ls_time-elapsed < ls_time-limit.

  CALL FUNCTION 'ENQUEUE_READ'
    EXPORTING
      gname                 = TABLE_NAME
      garg                  = TABLE_KEY
    TABLES
      enq                   = lt_enq
    EXCEPTIONS
      communication_failure = 1
      system_failure        = 2
      OTHERS                = 3.

  IF lt_enq[] IS INITIAL.
    EXIT. " object is not locked
  ENDIF.

  GET TIME STAMP FIELD ls_time-now.

  ls_time-elapsed = cl_abap_tstmp=>subtract(
    tstmp1 = ls_time-now
    tstmp2 = ls_time-start
  ).

ENDWHILE. " elapsed time

Assigned Tags

      24 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Michelle Crapo
      Michelle Crapo

      I like this one!  It's sadly, one that I find I use a lot.

      A nice add to this one is to read the lt_enq-guname if the time runs out. Then display it as locked by that user.  I've also had a few request to change it from user name to actual person name.

      Author's profile photo Amy King
      Amy King
      Blog Post Author

      You can definitely take the check further or even swap out the call to ENQUEUE_READ for some other thing you're waiting for, like a dependent record to be created.

      Author's profile photo Margaret Kreytak
      Margaret Kreytak

      This solution is more elegant than my usual solution which just runs a random number of times.  Thank you.

      Author's profile photo Amy King
      Amy King
      Blog Post Author

      Thanks Margaret!

      Author's profile photo Peter Inotai
      Peter Inotai

      Nice series.

      There was a similar blog with very interesting discussion on the same topic some time ago:

      https://blogs.sap.com/2019/01/18/while-n-seconds-killing-the-wait-up-to-n-seconds/

      Peter

      Author's profile photo Amy King
      Amy King
      Blog Post Author

      It's a common problem I'm sure. It's great that these forums exist to share solutions.

      Author's profile photo Tomas Buryanek
      Tomas Buryanek

      It is not much known. But you can also wait fraction of second with WAIT UP TO command 🙂

      WAIT UP TO '0.1' SECONDS.
      Author's profile photo Amy King
      Amy King
      Blog Post Author

      This is true, but maybe your check will succeed in 0.12 seconds. With two waits of 0.1 seconds you'll end up waiting 0.2 seconds. Think of what you could do with the 0.08 seconds you've saved! LOL. For many programs, the code snippet above is likely overkill, but it also could come in handy for processing very large sets of data where those 0.08 seconds add up to a meaningful time saving.

      Author's profile photo Peter Inotai
      Peter Inotai

      Unfortunately it's possible only for recent releases (see: https://blogs.sap.com/2019/01/18/while-n-seconds-killing-the-wait-up-to-n-seconds/#comment-448388 )

      Author's profile photo Tomas Buryanek
      Tomas Buryanek

      I remember that it worked in ABAP 7.31 at least…

      EDIT: I might be wrong. More info below.

      Author's profile photo Sandra Rossi
      Sandra Rossi

      milliseconds since 7.40 SP08 cf ABAP release news

      Author's profile photo Tomas Buryanek
      Tomas Buryanek

      Thank you. But before 7.40 this worked also. They maybe changed only the docu description or some internal definitions...
      You can find mentions about "decimal" WAIT UP TO as far as 2008 go... or so... And I remember that it worked in 7.31.

      WAIT UP TO '0.5' SECONDS.
      Author's profile photo Sandra Rossi
      Sandra Rossi

      Did you make measurements to make sure that ‘0.5’ and 1 did not wait both 1 second? (conversion to integer type)

      But maybe the data object was passed directly as-is to the kernel, so it would depend on the kernel only, who knows.

      Author's profile photo Tomas Buryanek
      Tomas Buryanek

      Yes of course I did few tests before. It waited for a half second, not one second.
      EDIT: Tested it now on some old 7.21 server and this waited 10 seconds, so fractions do not work there. Can somebody on 7.31 test how long it wait 🙂 ?

      DO 10 TIMES.
        WAIT UP TO '0.5' SECONDS.
      ENDDO.
      WRITE: / 'Done'.

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      7.31 here (EHP6) - 10 seconds. Captured timestamp before and after. Bummer...

      Author's profile photo Tomas Buryanek
      Tomas Buryanek

      Thank you Jelena! I was probably wrong, or it was dependent also on some other SAP component/s version.

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Thanks for bringing this up though! Now I'll keep in mind this would be possible for us in future.

      Author's profile photo Sandra Rossi
      Sandra Rossi

      One question for which I have no answer is the impact of repeating code continuously on the CPU load. I observed that a counting loop of a number of seconds has a high impact on the CPU load (and impacts other parallel processes), but a WAIT of the same duration seems to have no impact. So maybe a little WAIT inside the loop is better.

      Author's profile photo Amy King
      Amy King
      Blog Post Author

      That would be in interesting comparison test. There is probably some balance that needs to be considered between burden on the user (processing time) and burden on the CPU (resources). This is great insight Sandra, thanks for sharing. I always find it interesting when different solutions in ABAP yield the same end result yet have different impacts on performance.

      Author's profile photo Lars Hvam
      Lars Hvam

      Also with above solution, it will keep querying the enqueue server, which is a central component. So instead of impacting one application server, it can potentially impact the full landscape of application servers.

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Thanks for sharing! This is a pretty common problem, so I appreciate the solution.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      It is common. So common that maybe a solution should be provided as standard.

      Something like

      WAIT FOR UNLOCK ON <table_key>

      or perhaps along with ENQUEUE and DEQUEUE FM, we have WAITQUEUE...

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      I would totally vote for that! CC Horst Keller

      Author's profile photo Enno Wulff
      Enno Wulff

      In most cases this problem results of objects booked in update task.

      So it can be solved using SET UPDATE TASK LOCAL.