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.
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.
PROCEDURE Main
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
EXIT
ENDIF
ENDDO
IF lRLock
REPLACE cust->LastName WITH cLastName , ;
cust->FirstName WITH cFirstName
DbUnlock()
ENDIF
ENDIF
CLOSE Cust
RETURN
// 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 --
EXIT
ENDIF
nRelation ++
ENDDO
ELSE
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.
ENDIF
slLockAll := .T. // reset STATIC
saLocked := {} // variables
ENDIF
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.