6 Example Operations
The DBLOCK statement operates in one of twelve modes. Modes 1 through 6 apply a write lock to the section specified; modes 11 through 16 apply a read lock to the section specified. Modes 1, 2, 11, and 12 are used to lock an entire database. Modes 3, 4, 13, and 14 are used to lock a data set. Modes 5, 6, 15, and 16 are used to lock an entry or group of entries specified by a lock descriptor.
A program can read a section of the database without locking it even if the section is locked by another program. If a second program is modifying the database during the read, unexpected results can occur. For example, while a program is performing chained GET's, the address of the next entry can be modified by a second program. To prevent this, the appropriate data set or entries in the data set should be locked.
Locks used to protect read operations should be read locks. A read lock prevents other programs from getting a write lock on an entry, thus preventing any modification of that entry. A read lock will not prevent other programs from getting a read lock on the same entry. The shared read modes allow for greater access to the database while preventing write operations.
The DBLOCK operation makes no modifications to the database itself. The entries locked do not have to exist in the database. This will be the case when a new entry is created by a DBPUT.
If @ is specified for the data set name, Eloquence DBMS interprets this to mean "lock all data sets" (meaning, the whole database. This is equivalent to the operation of modes 1, 2, 11, and 12). Similarly, if @ is specified for the item name, the interpretation is "lock all items" in the specified data set (meaning, lock that data set; equivalent to modes 3, 4, 13, and 14).
Eloquence DBMS also allows set name to be @ with item name, relational operator, and value specified for a desired entry value. This means "lock this entry wherever it occurs in any set".
A lock descriptor is a string expression with a very specific format, as described below:
= equal
>= greater than or equal
<= less than or equal
EQ equal
GE greater than or equal
LE less than or equal
NOTE: Lexical comparison is currently handled the same as ASCII comparison.
CHR$(0) & CHR$(21) & Set$ & Item$ & "%<=" & "GEORGE"NOTE: The example above implies a CPU with big endian byte order (eg. HPPA). For litte endian system (eg. Intel) the CHR$(0/21) must be exchanged.
The one-word integer length field is formed by two-byte values using the CHR$ function. The length value must be carefully specified to include the complete descriptor. The Set$ and Item$ strings must have a current length of 16.
The PACK USING statement can also be used to construct a predicate. The next sequence could be used in a program to lock PRODUCT-NO=16117 in the data set PRODUCT.
100 INTEGER N, Product_no, Stat(9) 110 DIM Q$[40],Lock_set$[16],Lock_item$[16],Relop$[2] 120 Product_no=16117 130 Lock_item$="PRODUCT-NO " 140 Lock_set$="PRODUCT " 150 Relop$="= " 160 N=19 170 Mode=5 180 PACK USING 190;Q$ 190 PACKFMT N, Lock_Set$, Lock_item$, Relop$, Product_no 200 DBLOCK (Base$, Q$, Mode, Stat(*)) * * *The disadvantage of these methods is that the programmer must manually specify the descriptor length and guarantee the correct length for each field. The PREDICATE statement computes the descriptor length and insures that the format is correct. To create the descriptor in the previous example, the programmer need only write the following:
500 PREDICATE Q$ FROM "PRODUCT","PRODUCT-NO","=",16177The programmer can often choose from many equivalent lock sequences. For example, to apply a read lock to the data set LOCATION, the programmer could use any of the following sequences:
200 INTEGER N, Stat(9) 210 DIM Lock_set$[16],Lock_item$[16],Q$[40] 220 Lock_item$="@" 230 Lock_set$="LOCATION" 240 N=17 250 PACK USING 170;Q$ 260 PACKFMT N,Lock_set$,Lock_item$ 270 DBLOCK (Base$,Q$,15,Stat(*)) * * *or
200 Mode=13 210 Lock_set$="ITEM-MASTER" 220 DBLOCK (Base$,Lock_set$,Mode,Stat(*)) * * *or
200 PREDICATE P$ FROM "ITEM-MASTER","@" 210 DBLOCK (Base$,P$,16,Stat(*)) * * *Multiple descriptors can be combined in a predicate to specify complex locks. Descriptors can be combined by concatenation or by specifying multiple set-item-value groups on the PREDICATE statement. The following example locks the data set LOCATION as well as all values of PRODUCT-NO less than or equal to 10,000 in the data set PRODUCT.
110 INTEGER Lock_itemnum,Stat(9) 120 DIM Q$[40],Lock_set$(1:2)[16],Relop$[2] 130 Lock_item$="@" 140 Lock_itemnum=14 ! ITEM #14 for PRODUCT-NO. 150 Lock_set$(1)="LOCATION " 166 Lock_set$(2)="PRODUCT " 170 Relop$="<=" 180 Keyinfo=10000 190 Mode=5 200 PREDICATE Q$ FROM Lock_set$(1),Lock_item$;Lockset$(2), Lock_itemnum,Relop$,Keyinfo 210 DBLOCK (Base$,Q$,Mode,Stat(*)) * * *The maximum length of a predicate string is 4095 bytes.
It is also necessary to restrict entry lock requests such that at any one time only a single item name in a data set can be used for locking purposes. Lock requests on different values of the same item are acceptable. However, the locking system cannot determine if the collection of entries locked using different item names have any entries in common. In this case, DBLOCK assumes that a conflict exists and queues the later request or returns a status error.
When a request is queued, no other request which would conflict with the request in queue is granted. For example, assume program A has locked a data entry in data set X, and program B wants to lock data set X and data set Y. Program B's request is queued. When program C requests to lock a data entry in data set Y, that request is queued because program B is waiting to lock data set Y.
When using DBLOCK wait modes, the programmer should be careful to avoid possible deadlock conditions. If a program makes multiple resource requests using the commands DBLOCK, LOCK# or REQUEST, a potential deadlock can occur if another program is also making requests for the same resources. For example, suppose program A holds resource 1 and is queued waiting for resource 2 which is held by program B. If program B makes a wait request for resource 1, a deadlock situation occurs. Programs requesting the same resources can avoid deadlock by making their resource requests in the same order.
The following table summarizes the conditions for granting a lock:
Lock Request | Conflicting Lock | Action |
---|---|---|
Whole databasewrite-lock | Whole database already write-locked. | Wait |
Whole database already read-locked. | Wait | |
One or more sets write-locked. | Block and wait * | |
One or more sets read-locked. | Block and wait * | |
One or more item/values write-locked. | Block and wait * | |
One or more item/values read-locked. | Block and wait * | |
Whole database-read-lock | Whole database already write-locked. | Wait |
Whole database already read-locked. | Grant lock | |
One or more sets write-locked. | Block and wait * | |
One or more sets read-locked. | Grant lock | |
One or more item/values write-locked. | Block and wait * | |
One or more item/values read-locked. | Grant lock | |
Whole data setwrite-lock | Whole database already write-locked. | Wait |
Whole database already read-locked. | Wait | |
Requested set write-locked. | Wait | |
Requested set read-locked. | Wait | |
One or more item/values in requested set write-locked. | Block and wait * | |
One or more item/values in requested set read-locked. | Block and wait * | |
Whole data setread-lock | Whole database already write-locked. | Wait |
Whole database already read-locked. | Grant lock | |
Requested set write-locked. | Wait | |
Requested set read-locked. | Grant lock | |
One or more item/values in requested set write-locked. | Block and wait * | |
One or more item/values in requested set read-locked. | Grant lock |
* "Block" means that no more locks capable of impending the request will be granted.
Lock Request | Conflicting Lock | Action |
---|---|---|
Item/value inset write-lock | Whole database already write-locked. | Wait |
Whole database already read-locked. | Wait | |
Set write-locked. | Wait | |
Set read-locked. | Wait | |
Requested item/value write-locked. | Wait | |
Requested item/value read-locked. | Wait | |
Different item in set write-locked. | Block and wait * | |
Different item in set read-locked. | Block and wait * | |
Item/value inset read-lock | Whole database already write-locked. | Wait |
Whole database already read-locked. | Grant lock | |
Set write-locked. | Wait | |
Set read-locked. | Grant lock | |
Requested item/value write-locked. | Wait | |
Requested item/value read-locked. | Grant lock | |
Different item in set write-locked. | Block and wait * | |
Different item in set read-locked. | Grant lock |
* "Block" means that no more locks capable of impending the request will be granted.