HOLD (exclusive record access)

Top  Previous  Next

 

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:

RELEASE

NEXT

PREVIOUS

WATCH

GET

REGET