| **Navigation:**  [[introduction.htm|Language Reference]] > 13 - Built-in Functions >====== HOLD (exclusive record access) ====== | [[help help window access .htm|{{btn_prev_n.gif|Previous page}}]][[introduction.htm|{{btn_home_n.gif|Return to chapter overview}}]][[hide blank a control .htm|{{btn_next_n.gif|Next page}}]] | | || **HOLD(**// entity// [,//seconds//]**)** {{blk2blue.jpg|blk2blue.jpg}} | **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:** [[release release a held record .htm|RELEASE]] [[next read next record in sequence .htm|NEXT]] [[previous read previous view record in sequence .htm|PREVIOUS]] [[watch automatic concurrency check .htm|WATCH]] [[get read a record or entry .htm|GET]] [[reget re get record .htm|REGET]]