Retry record locking

fjpomares

New Member
I want a user can retry to lock a record as following:

user 1 run:
Code:
FIND FIRST CABEOFERV EXCLUSIVE-LOCK NO-WAIT NO-ERROR.
MESSAGE "pausa" VIEW-AS ALERT-BOX.
RELEASE CABEOFERV.
User 2 run:
Code:
DEFINE VARIABLE lRetry AS LOGICAL  NO-UNDO.
FIND FIRST CABEOFERV NO-LOCK.
REPEAT:
  FIND CURRENT CABEOFERV EXCLUSIVE-LOCK NO-WAIT NO-ERROR.
  IF NOT AVAILABLE CABEOFERV THEN DO:
      IF LOCKED CABEOFERV THEN DO:
        MESSAGE "Locked ¿Retry?" VIEW-AS ALERT-BOX QUESTION BUTTON YES-NO UPDATE lRetry.
        IF lRetry THEN do:
            NEXT.
        END.
        ELSE
            RETURN.
        END.
        ELSE DO:
            MESSAGE "Deleted" VIEW-AS ALERT-BOX ERROR.
            RETURN.
        END.
     END.
     ELSE IF CURRENT-CHANGED CABEOFERV THEN DO:
        MESSAGE "Modified" VIEW-AS ALERT-BOX INFORMATION.
        RETURN.
    END.
END.

The code of User2 show "locked ¿Retry?" while User1 hold the record locked. But it happens that even if User1 release the record, the message "Locked ¿Retry?" still appears... the FIND CURRENT not aware that the record has been released

Is there any incorrect in the code?

If I replace FIND CURRENT CABEOFERV... for FIND CABEOFERV WHERE ... it work ok, but I can't ask for CURRENT-CHANGED cabeoferv

What can I do?

Thanks.
 
Last edited by a moderator:

RealHeavyDude

Well-Known Member
Please wrap the code in code tags for better readability.

Is this real production code or just a test to prove a point?

On a hunch: Your problem might be buffer scope and the usage of the release statement. You don't wanna see a release statement in production code because it doesn't do what you might think it should do. For some it is the root of all evil. Instead you should think about buffer scope. In you first procedure the buffer and transaction scope most likely is the whole procedure ( given your code ). The release statement does NOT release the lock - instead it just makes sure that some basic validation takes place and writes the contents of the buffer to the database. Again, it does NOT release the lock. The lock is released a the end of the transaction scope and, if the buffer scope is larger, will be downgraded to a share lock.

Heavy Regards, RealHeavyDude.
 

fjpomares

New Member
Please wrap the code in code tags for better readability.

Is this real production code or just a test to prove a point?

On a hunch: Your problem might be buffer scope and the usage of the release statement. You don't wanna see a release statement in production code because it doesn't do what you might think it should do. For some it is the root of all evil. Instead you should think about buffer scope. In you first procedure the buffer and transaction scope most likely is the whole procedure ( given your code ). The release statement does NOT release the lock - instead it just makes sure that some basic validation takes place and writes the contents of the buffer to the database. Again, it does NOT release the lock. The lock is released a the end of the transaction scope and, if the buffer scope is larger, will be downgraded to a share lock.

Heavy Regards, RealHeavyDude.


It's a test.

It work the same without RELEASE CABEOFERV.

While user1 stay in message "pausa" the record is locked and the User2 stay in message "Locked ¿Retry?". When User1 end, I check that the record is not locked (The _lock table is empty), however in user2 code, the repeat FIND CURRENT follow saying that the record is locked.
 

tamhas

ProgressTalk.com Sponsor
Point being that you need to introduce transaction/buffer scope in the first procedure. E.g., wrap what you have in

DO FOR CABEOFERV:

END.

and drop the pointless RELEASE.
 

fjpomares

New Member
I already know the reason for the problem.

Since the first time that FIND CURRENT return NOT AVAILABLE AND LOCKED, the record is no longer available for each REPEAT FIND CURRENT iteration. It is necesary find the record newly.

Tanks.
 
Top