Get STATEMENT CLAUSES FOR SIMULTANEOUS UPDATE

PURPOSE:  The GET statement is used to retrieve records from a DS for use in a PM.  Under the Concurrent Queued environment, which allows multiple-user update of a given DS, a record may be retrieved for shared use or exclusive use.  A record that is retrieved for shared use is said to be reserved.  Reserved records may be concurrently accessed by others for input, but are not available to another user who wants to update.  A record that is retrieved for exclusive use is said to be locked.  The GET statement must put a temporary lock on a record during the time that it is being updated, to prevent any other user from accessing it, for either input or update.  In other words, for the period during which the record is being read it is not available to any other user for either input or update.  However, all other records in the DS are still available for both input and update.

A second option of GET that is available only under simultaneous update is the MULTIPLE option.  It allows the user to reserve or lock more that one record at a time.

General Form

GET FROM designator [MULTIPLE] [LOCKED] [/USE/ DOMAIN name] retrieval method

[HUSH] [IF;UNLESS clause]

where:

FROM designator, [/USE/ DOMAIN name], retrieval method, [HUSH], and [IF;UNLESS clause] are described in the primary discussion of GET, in Chapter 13.

MULTIPLE allows more than one record from a related DS to be reserved or locked at the same time.  The record will remain reserved or locked until a FREE statement is executed or until the PM terminates.

The MULTIPLE option is generally used only when the PM needs to hold on to a group of retrieved records for use (such as for subtotaling) before they are released.  However, use of the MULTIPLE option can quickly exhaust the user’s quota of resources available for queuing.  It is almost always preferable to design an application so it does not use MULTIPLE, if that is possible.  (See discussion of “Locking Resources” later in this chapter for details.)

GET MULTIPLE and GET are mutually exclusive ways to retrieve records.  These two ways may not be used at the same time on the same designator.  A FREE statement must be specified before changing from GET to GET MULTIPLE or vice versa.

LOCKED specifies exclusive control of a record.  It cannot be accessed by any other user for either input or update while it is locked.  A GET statement must specify the LOCKED option in order to subsequently PUT or DELETE the record.

A locked record is released from control when it is rewritten by a PUT statement, removed by a DELETE statement, or when another GET is executed on the same designator (assuming that MULTIPLE is not in effect).  If the PUT or DELETE statement fails, then the record will not automatically be freed.  In this case, the record can be freed in one of the following ways:

If a GET statement queues the last record of a DS for shared access (i.e., without the LOCK option), a subsequent CREATE statement in the PM for the DS will fail because the CREATE statement will be unable to queue the DS for exclusive access.  This can be avoided by:

NOTES:  Record level queuing actually occurs on a block level.  When a record is reserved by a GET statement, all records in the same block are reserved.  The same principle applies to record locking.  A GET LOCKED on a record actually locks all records in the same block.

If @RECORD.WAIT seconds elapse while the GET statement waits for a busy record, the GET fails, @AUX is set to “BUSY”, and the PM continues.  It is suggested that PM’s executing in the Concurrent Queued environment regularly check for the value of @AUX to determine if a record has been successfully retrieved.

The MULTIPLE and LOCKED options may only be used under the Concurrent Queued environment;  that is, only when record-level queuing has been established by specifying operations in an ALLOWING clause in the RELATE statement.

Example

The following four examples illustrate record reserving and locking using the MUTILPE and LOCKED options.  (The examples are for illustration only, and do not necessarily reflect exactly how ACCENT R buffering is handled).  Assume the GET statement retrieves records sequentially (from record 1 to 2, to 3, etc.).  In this example, the third record has just been retrieved.  These examples assume two records per block (i.e., records 1 & 2 in one block, 3 & 4 in another block, etc.).

(1) Example of GET

(2) Example of GET LOCKED

Record #

Status

Record #

Status

 

 

GET

Free

Free

Reserved

Reserved

free

 

GET LOCKED

Free

Free

Locked

Locked

free

Records are retrieved and reserved, then released when the next block is accessed.  The reserved records may be concurrently accessed by others for input but not for update.

Records are retrieved in locked mode, then released when the next block is accessed.  The locked records may not be concurrently accessed by others for either input or update.

 

(3) Example of GET MULTIPLE

(4) Example of GET MULTIPLE LOCKED

Record #

Status

Record #

Status

 

 

GET MULTIPLE5

reserved

reserved

reserved

reserved

free

 

GET

MULTIPLE

LOCKED 

locked

locked

locked

locked

free

All reserved records stay reserved until a Free Statement is issued or the PM ends.  Reserved records may be accessed by others for input but not for update.

 

Records remain locked until a FREE statement is issued or the PM ends.  Locked records may not be accessed for either input or update until they have been freed.

The following chart shows several combinations of GET, LOCK, and FREE statements, and the results for each combination.

Previous GET

Current Statement

Explanation/Error Type

none

FREE

No error

none

LOCK

No error

GET

FREE

No error

GET

LOCK

Error

GET

GET MULTIPLE

Error, @AUX = “MULT

GET

PUT

Error, @AUX = “LOCK

GET

GET LOCKED

No error, **

GET LOCKED

GET

No error, **

GET MULTIPLE

GET

Error, @AUX = “MULT

GET MULTIPLE

GET MULTIPLE LOCKED

Error, @AUX = “MULT

**Expensive because the block containing the record must be read from disk, even if it is the same block just read by the preceding GET.

The example below shows a PM where a GET is followed by a GET MULTIPLE.  Notice the error message and the value of @AUX as it is displayed.  To make this example work, a FREE statement should be inserted between lines 50 and 70.

*LIST PM SAMPLE
00010   CONTROL
00020   RELATE DS SAMPLE AS A FOR UPDATE ALLOWING UPDATE
00030   RELATE TERMINAL AS REPORT 1
00040   DETAIL
00050   GET FROM A FIRST
00060   PRINT NUMB,5B,DEPT,5B,SALES
00070   GET FROM A MULTIPLE NEXT
00080   TYPE @AUX
*USE PM SAMPLE
1 AAA 500.00
GET NEXT FROM A FAILED AT PM LINE 70
MULT
*