2014 May 30 2:51 PM
I have the need to know user AND mode wise, if I have a lock over the data and if I'm the owner of the lock (i.e. the one that called ENQUEUE successfully).
I already did solve this partially using f.m. ENQUEUE_READ. But as you know, when using exclusive lock mode (types E or X), if you request a new lock even with your own user but in a different mode, you get the same FOREIGN_LOCK exception as if you were another user.
So, using ENQUEUE_READ alone is not enough, because even if my user is in the lock table, it doesn't necesarily mean I have the data locked in THAT mode / session.
What I did is to compare the fields GTHOST and GTWP returned by ENQUEUE_READ, to the output of funcion module TH_GET_OWN_WP_NO (WP_NO + SY-HOST).
So I'm comparing the workprocesses. But I'm not sure if this will always work, because I understand workprocesses are taken and released constantly (for example when user input is required). So I'm afraid at certain points in time the workprocess I'm in will not necessarily be the one on which the ENQUEUE was requested.
Are there any other ways to do this? The obvious answer is to retry an ENQUEUE and use E mode (if I'm in the owner mode, it won't fail, just incrementing the counter, so I can do a DEQUEUE right away to leave it as before), but I prefer to avoid this option.
Thanks!
PS: I'm using SCOPE = 1 to have control over DEQUEUEs.
EDIT: a third alternative (which I like even less since it encapsulates an internal system call):
PERFORM get_c_owner IN PROGRAM saplsena IF FOUND CHANGING user usvb .
Please post if you know others!
2014 Jun 02 5:48 PM
I might be not the only one unable to understand the question... What are you asking exactly? The subject says "get lock owner", but it seems you got this covered already.
Also not sure I understand the significance of getting further detail on the lock (beyond the owner). What difference would this information make and what would you do with it?
2014 Jun 02 5:48 PM
I might be not the only one unable to understand the question... What are you asking exactly? The subject says "get lock owner", but it seems you got this covered already.
Also not sure I understand the significance of getting further detail on the lock (beyond the owner). What difference would this information make and what would you do with it?
2014 Jun 02 6:13 PM
Jelena, I'm asking for the cleanest way possible to know if the current user is the lock owner in the current mode.
I'll be doing the ENQUEUE when the user enters my transaction. The first user would succeed, while if some users enter after a while, they wouldn't (because the first one is still inside). Later in time, I want to know if the current user / mode is the one holding the lock, so I can allow some processing. This way of locking avoids the recurrent problem of having to read the same data again when the lock is set from inside the transaction, because it may have changed from the moment it was read (yes, the drawback is that you have to exit and reenter to retry the lock. But this is the behaviour requested).
For this, ENQUEUE_READ is not enough by itself. It just returns the username and the owner keys, which I find no clean function module to get for the current mode, in order to compare.
So, the options I found were:
1) Compare workprocesses using TH_GET_OWN_WP_NO (discarded because of the reason above, I'm afraid workprocess may be swapped with another)
2) ENQUEUE initially in mode E, then retry a second mode E ENQUEUE. The owner won't fail, the others will. This option I'm using so far.
3) "PERFORM get_c_owner IN PROGRAM saplsena" returns the owners in the current mode, which can be compared to the ENQUEUE_READ output. But this is not exposed by any general purpose function module or method (at least I found none). There's plenty of standard code which doesn't even do the external perform but just the direct system call (CALL 'C_ENQUEUE' ID 'OPCODE' FIELD '7'..), which is a no-no in custom programs.
So, my question is if you know a cleaner way to achieve this. I think there isn't, but hoped anyone knows better.
Regards
For you to get an idea, the function module ENQ_OWNER_GET is the closest to what I want. But it uses an irrelevant lock object first, and also returns only one of the two possible owners (ENQKEY missing). It's not a general purpose module. Message was edited by: Alejandro Bindi
2014 Jun 03 3:24 AM
Couple of thoughts - firstly ENQUEUE_READ returns an array of type SEQG3 which contains a "GMODE" column... my (very) brief testing indicates this returns X, E, O etc...however it doesn't seem to clearly identify which SAP session for the user has the lock i.e. it could be a different user session than the current one.
So when we've needed to keep track of whether or not the current user session is holding the enqueue we simply set a global variable (e.g. "g_have_lock = abap_true") that we test thereafter... sometimes we wrap this logic up in a global class so lower layers of logic can query a class attribute / method.
Jonathan
2014 Jun 03 7:05 AM
Hi Alejandra,
I'm also unsure what the problem is.
If an ENQUEUE of a lock object for a specific key is successful, set a flag and keep the key in a workarea in your program, and you will know, that your user has locked the key in this mode.
If you can't lock a object with a specific key, it might be locked by yourself or another user. This info you can get from fm ENQUEUE_READ.
So you have all informnation you need.
Regards,
Klaus
2014 Jun 03 1:34 PM
Jonathan and Klaus,
The "global" flag solution is of course the simplest and how I initially did it. But what if some other called program / f.m. / method / whatever, does a DEQUEUE_ALL...or what if I'm using scope 2 and a COMMIT WORK releases the lock because an update f.m. is called? The flag is not synchronized any more.
That's why I set out to get this information in real time.
Anyway, I guess there are no more available solutions than the ones already mentioned, so I'll consider the thread answered.
Regards.
| User | Count |
|---|---|
| 4 | |
| 2 | |
| 2 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |