Functions and Directives

Function RLock() Foundation

Locks current record for SHARED write access.

RLock() --> lSuccess

The return value of RLock() is .T. (true) if the current record in a work area was locked for SHARED write access. Otherwise .F. (false) is returned.


The database function RLock() locks a record for write access and prevents write access by other work stations. This capability is required in a multi-user application in network environment when a user is changing data in a record which might be in use at the same time by another user. When the record could be locked, RLock() returns the value .T. (true). The record is then only available for read access to other users until the record lock is released with DbUnlock() or a command like UNLOCK or CLOSE.

A record must be locked with RLock() when file operations change a record. Commands like @..GET, RECALL, DELETE or REPLACE and the function FieldPut() belong to this group.

After each call of RLock() only one attempt is made to lock the data record in a work area. When the function is used without the alias operator, the attempt to lock the record occurs in the current work area.

Existing record locks are released by Rlock().

When relations are defined (using SET RELATION or DbRelation()) for the file, the dependent files may also need to be locked. Automatic locking of all dependent records does not occur using RLock().

// The example shows the use of RLock() before data is written 
// to a file. When the lock fails, a warning is output on the 
// screen using Alert() and the user must decide whether another 
// attempt to lock the record should be made. 

   LOCAL cLastName, cFirstName, lRLock 

   USE Customer ALIAS Cust SHARED NEW 
   cLastName  := Cust->LastName 
   cFirstName := Cust->FirstName 

   @ 10,10 SAY " Last name:" GET cLastName 
   @ 11,10 SAY "First name:" GET cFirstName 

   IF Updated() 
      DO WHILE .NOT. ( lRLock := RLock() ) 
         IF Alert( "record is locked at this time", ; 
                   { "Retry", "Cancel" }    ) == 2 

      IF lRLock 
         REPLACE cust->LastName  WITH cLastName   , ; 
                 cust->FirstName WITH cFirstName 

   CLOSE Cust 
Lock records in all dependent work areas

// The example contains a user-defined function which 
// locks the record in the current (parent) work 
// area plus the records in all dependent child work 
// areas (if they exist) 

FUNCTION RlockRelation() 
   STATIC saLocked  := {}, snRecursion := 0, slLockAll := .T. 
   LOCAL nChildArea 
   LOCAL nRelation := 1 
   LOCAL lLocked   := RLock()        // lock record in the 
                                     // current area 
   IF lLocked                        // lock is set, 
      AAdd( saLocked, Select() )     // save area 

   ** Lock all child work areas 
      DO WHILE .NOT. ( nChildArea := DbRSelect(nRelation) ) == 0 
         snRecursion ++              // recursive call 
         IF (nChildArea)->( RlockRelation() ) 
            snRecursion --           // decrement 
         ELSE                        // recursion counter 
            snRecursion -- 
         nRelation ++ 
      slLockAll := .F.               // a record could not 
   ENDIF                             // be locked 

   IF snRecursion == 0 
      IF .NOT. slLockAll             // release record locks 
                                     // set 
         AEval( saLocked, {|nArea| (nArea)->(DbUnlock()) } ) 
         lLocked := .F. 
      slLockAll := .T.               // reset STATIC 
      saLocked  := {}                // variables 

RETURN lLocked 

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.