Determining lock status

MHotovec

Member
Forgive me if this turns out to be an easy answer, but I've had my nose stuck in the Progress books for the last couple hours and haven't figured it out.
Is there a way to determine if a particular record is in exclusive-lock status by another user without actually trying for an exclusive-lock myself? I'm familiar with the find first (record) exclusive-lock no-error no-wait method. But that gives me an exclusive-lock that I don't need.

Any hints would be greatly appreciated!

Mark.
 

NickA

Member
VST

There's always the VST's (Virtual System Tables) as long as you have them enabled, that is.

For more info refer to Progress KB article 19136.

HTH
 
I'm using the LOCKED instruction in this way :



FIND table_name WHERE bla bla bla
EXCLUSIVE-LOCK NO-ERROR NO-WAIT.
IF AVAILABLE table_name THEN
DO:
ASSIGN your new values to table_name.
END.
ELSE
DO:
IF LOCKED(table_name) THEN
MESSAGE "This table is locked by another user".
END.
 
U

Unregistered

Guest
Mark didn't want to try for an exclusive lock though!

Um, don't mean to cause offense Olivier, but from Marks original post, attempting an exclusive lock was exactly what he was trying to avoid - his reasons being his own, I guess. Perhaps he could give us a little more info on exactly what he's trying to achieve?

An additional benefit of using VST's is that you can obtain the ID of the user who's actually got the record locked - very useful, and something plain old unadorned 'NO-WAIT..IF LOCKED' doesn't give you.
 

MHotovec

Member
Thanks all for the info so far. As it is I've learned something, and that's always good!

The short version of what I'm trying to accomplish is this;
In our world (or at least the part I'm working with) we create sales order, and purchase orders that are linked to them. When createing or modifying the sales order the user holds an exclusive lock on the order header record and all order line records for the entire duration. It could be serveral minutes before they are done and the records are released. When creating a linked PO the user has an exclusive lock on the same records just long enough to change some values in the records.
What I don't want to happen is for a buyer to try to create a purchase order at the same time the sales order is being modified by a sales person because that could cause some business-type problems later on in the cycle. To prevent that I'd like to check to see if there is a lock on the order header record. If so then they buyer would be notified to try again later.
As it is I've written a little something that gives me a record lock for longer than I really need, but it's not as bad as it COULD be. As far as I'm concerned the shorter the lock the better.

Mark
 

fabio_prando

New Member
Try this...

Hi Mark !

I had the same experience and I've got a solution... I don't know if its the best one, but it worked.

I used a find < table > where < table.id > = "???" NO-LOCK.

This way, the user can use the record without lock it.

When the user try to save the changes, I used a "FIND CURRENT < table > EXCLUSIVE-LOCK".

After that I assigned the fields and i used RELEASE < TABLE >.

This reduce the time that the record stay locked.

I hope it can help you !

Fábio Prando
System Analyst - Brazil
 

mra

Junior???? Member
Hi Mark!

Locking records for as log a period as you describe, is a bad idea. What if the Sales person leaves the screen, falls and breaks and arm or a leg and goes to the hospital, Who is responsible for releasing the lock he or she created. It might stay there for quite a while. :D

In general it is better to use optimistic locking as described by Fábio Prando. You can use the locked and current-changed functions to determine if another user has locked or changed the record while it was being edited.

If you have to post data to the database, that the Buyers is not allowed to see, use state flags on the Order record.

Like 1=Created, 2=being processed, 3=Ready, 4=closed.


Hope you find it useful
Regards
Mike :)
 

MHotovec

Member
MRA
I (and everybody else here in IT) couldn't agree with you more about having a user hold a record lock for a long period of time. Unfortunatly the people who originally wrote our software didn't see it that way. Around here we have 'core' code which we can't modify, or even read as it's encrypted. And we have 'our' code which are various modifications we've made that sort of weave through the core code and do what we need done.

For those of you who're were wondering I chose to put an exclusive-lock inside a VERY short transaction loop. So my record lock last just long enough for me to find out if anyone else has the record, then I release the lock. It's not as elegant as I might have liked, but it gets the job done without holding a lock.

Mark
 

mra

Junior???? Member
Hi Mark!

Having code you can't change is like having an itch you can't scratch!!! :D

I've toyed around a little, and this is what I've found out.

In version 9.
The VST _UserLock is updated if a user locks a record. It is possible to query the table, to determine if a particular record is locked.

find first SOME-TABLE no-lock.
find first _UserLock where _UserLock._UserLock-Recid[1] = integer( recid( SOME-TABLE ) ) no-error.
if available _UserLock then
disp "The Record is locked" _UserLock._UserLock-Flags[1] .
else
disp "The Record is NOT Locked".


You must have VST enabled. This is not default in version 8 I think.

Hope you find it useful.

Regards
Mike :)
 

mra

Junior???? Member
By the way


Can someone explain this, because I shure can't!

The following code:

find first _File where _File._File-name = "SOME-TABLE".
find first _Lock where _Lock._Lock-table = _File._File-number no-error.
if available _Lock then
disp "Locked" _Lock._Lock-flags.
else
disp "Not locked".

Will run fine as long as SOME-TABLE is locked (exclusive/shared doesn't matter), but will run forever if the table is NOT locked. :confused:

No "Not locked" message will ever appear - Why??

Mike
 
Top