Navigation: Language Reference > 13 - Built-in Functions >====== HOLD (exclusive record access) ====== | |
HOLD( entity [,seconds])
HOLD | Arms record locking. |
entity | The label of a FILE opened for shared access or a VIEW whose component files are opened for shared access. |
seconds | A numeric constant or variable which specifies the maximum wait time in seconds. |
The HOLD statement arms record locking for a following GET, REGET, NEXT, or PREVIOUS statement in a multi-user environment. The GET, REGET, NEXT, or PREVIOUS flags the record as “held” when it successfully gets the record. Generally, this excludes other users from writing to, but not reading, the record. The specific action HOLD takes is file driver dependent. When the entity parameter is the label of a VIEW structure, HOLD operates on the primary file in the VIEW, only.
HOLD( entity ) | Arms HOLD so that the following GET, REGET, NEXT, or PREVIOUS attempts to hold the record until it is successful. If it is held by another workstation, GET, REGET, NEXT, or PREVIOUS will wait until the other workstation releases it. |
HOLD(entity , seconds ) | Arms HOLD for the following GET, REGET, NEXT, or PREVIOUS to post the “Record Is Already Held” error after unsuccessfully trying to hold the record for seconds. |
A user may only HOLD one record at a time. If a second record is to be accessed in the same file, the previously held record must be released (see RELEASE).
A common problem to avoid is “deadly embrace.” This occurs when two workstations attempt to hold the same set of records in two different orders and both are using the HOLD(entity) form of HOLD. One workstation has already held a record that the other is trying to HOLD, and vice versa. You can avoid this problem by using the HOLD(entity,seconds) form of HOLD, and trapping for the “Record Is Already Held” error after the GET, REGET, NEXT, or PREVIOUS statement.
Example:
ViewOrder VIEW(Customer) !Declare VIEW structure
PROJECT(Cus:AcctNumber,Cus:Name)
JOIN(Hea:AcctKey,Cus:AcctNumber) !Join Header file
PROJECT(Hea:OrderNumber)
JOIN(Dtl:OrderKey,Hea:OrderNumber) !Join Detail file
PROJECT(Det:Item,Det:Quantity)
JOIN(Pro:ItemKey,Dtl:Item) !Join Product file
PROJECT(Pro:Description,Pro:Price)
END
END
END
END
CODE
OPEN(Customer,22h)
OPEN(Header,22h)
OPEN(Detail,22h)
OPEN(Product,22h)
SET(Cus:AcctKey)
OPEN(ViewOrder)
LOOP !Process records Loop
LOOP !Loop to avoid “deadly embrace”
HOLD(ViewOrder,1) !Arm Hold on view, primary record only,try for 1 second
NEXT(ViewOrder) !Get and hold the record
IF ERRORCODE() = 43 !If someone else has it
CYCLE ! try again
ELSE
BREAK !Break if not held
END
END
IF ERRORCODE() THEN BREAK END !Check for end of file
!Process the records
RELEASE(ViewOrder) !release Primary held record
END
CLOSE(ViewOrder)
See Also: