Database and File Locking [ HP Transact Reference Manual ] MPE/iX 5.0 Documentation
HP Transact Reference Manual
Database and File Locking
It is important, especially for online interactive applications, to
establish a locking strategy at the time of system design. In general,
locking is related to the transaction, the basic unit of work performed
against a database. Typically, a transaction consists of several
Transact statements to locate and modify data. Devising a locking scheme
requires an understanding of locking levels, unconditional versus
conditional locking, how Transact handles locking, and how access mode
affects locking.
Locking Options Available with Transact
The Transact programmer has several options regarding database locking:
* Not locking at all by specifying NOLOCK on a SET(OPTION)
statement.
* Allowing Transact to handle the locking automatically by using
either:
* Default locking--Transact locks at the database level.
Choose this method of locking by setting optlock to 0 on
the SYSTEM statement. This is the default setting and
unconditional locking is used.
OR
* Optimized locking--locks at the database, data set, or
entry level, depending on the operation. Choose this
method of locking by setting optlock to 1 on the SYSTEM
statement. Conditional locking is used.
* Using the LOCK option on the LOGTRAN statement. This allows you
to specify locking for a database, a data set, or for several data
sets across a logical transaction. It also allows you to specify
conditional or unconditional locking. You must specify
SET(OPTION) NOLOCK prior to the LOGTRAN statement to ensure that
automatic locking does not operate for the verbs within the
transaction.
* Using the PROC statement to call the database-locking intrinsics
(DBLOCK and DBUNLOCK). See the TurboIMAGE/V or TurboIMAGE/XL
Database Management System Reference Manual for more information.
With no locking or with automatic locking, you have the additional
capability of specifying the LOCK option on individual database access
verbs, as explained in "Using the LOCK Option with the Database Access
Verbs" later in this chapter.
Avoiding Deadlocks in Transact Programs
A deadlock can also occur when there are conflicting locks within a
single program. This is uncommon due to the error checking provided by
Transact and the database, but can occur if you mix locking methods
injudiciously. For example, suppose that within a Transact program you
use DBLOCK through a PROC statement to lock a data set unconditionally.
Then you issue a data access verb, that invokes automatic default
locking, to request an unconditional lock on the database itself. The
request for the database lock cannot complete because the data set lock
must be released first. But the data set lock cannot be released because
the program is waiting for the database lock to be granted. The result:
deadlock due to conflicting locks within one program.
CAUTION The special MPE capability, Multiple RIN (MR), is required to
complete multiple, simultaneous locks on the same database.
Transact provides this capability. Use extreme caution when
employing a multiple-lock strategy. Hewlett-Packard does not
accept responsibility for possible deadlocks or system lockouts
that could result from the improper use of the MR capability.
Recommendations:
* Use multiple simultaneous locks only with conditional
locking, not with unconditional locking.
* Use multiple simultaneous locks only if absolutely
required, such as when locking more than one database.
* Use a consistent locking strategy. All programs using
multiple, simultaneous locks and concurrent access should
lock at the same level and in the same order.
In addition, if you are using Transact with unconditional
locking and multiple, simultaneous locks, there are two
situations you should avoid or, at least, handle very carefully.
They are:
* Using a file equation so as to have two names for the
same database, data set, or data entry.
* Combining Transact Default Locking with a PROC
statement to call DBLOCK and lock a data set or entry
unconditionally.
With Default Locking, Transact uses unconditional locking at the database
level. If you implement multiple simultaneous locks and allow concurrent
database access, either you must develop a locking strategy that does not
deadlock, or you must use one of the other methods of locking available
with Transact.
With Optimized Locking, Transact combines conditional locking at the
appropriate level with a retry loop, so that your program seems to wait
until the lock is granted. However, Transact retains control. If you
press Ctrl Y, the program is interrupted and Transact returns to command
mode with a > prompt. There is no possibility of a deadlock.
You can use the LOCK option on the LOGTRAN statement to specify whether
to use conditional or unconditional locking and what locking level to
use. Transact keeps track of any locks applied for transaction locking
and returns an error message if you attempt to issue conflicting locks.
To take full advantage of this protection, we recommend that you do not
combine other methods of locking with transaction locking within the same
program.
Of course, if you choose not to use locking, creating a deadlock is
impossible. This is only recommended if combined with read-only or
exclusive database access. Otherwise, you cannot ensure data integrity.
Understanding the Optimized Locking Scheme
All locks applied by optimized locking are conditional. Table 6-1 shows
the rules that Transact uses for optimized locking when determining the
level at which to lock. However, the Transact programmer need not know
these rules, since the rules are applied automatically. The rules are
presented for the programmer who needs to know the locking level to
assure the logical integrity of the database and to conform to a
pre-established locking strategy.
Table 6-1 summarizes the conditions affecting the locking level. The
first four columns present the conditions as boxes, alternate
possibilities appearing in the same column. For example, if you are
using the DELETE verb, you would pick the second box in the first column.
To the right of this box, you would find two boxes representing two
groups of modifiers. If you are using the CHAIN modifier, you would
choose the top box. There are two boxes to the right of this box. If a
PERFORM appears in the DELETE statement, you would choose the Using
PERFORM? box. If the DELETE statement includes a LOCK, then you would
choose the Using LOCK? box in the next column. In the final column, the
Locking Level box, the entry "Database" indicates that the combination
"DELETE(CHAIN)..., LOCK,PERFORM=..." results in a database level lock.
Table 6-1 Automatic Locking Using the Optimized Locking Scheme
-----------------------------------------------------------------------------------------------------
| | | | | |
| Verb | Modifier | Using | Using | Locking |
| | | PERFORM? | LOCK? | Level |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| FIND | CHAIN | Yes | Yes | Data Base |
| OUTPUT | RCHAIN | | | |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | | No | No Lock |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | No | Yes | Entry |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | | No | No Lock |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | None | Yes | Yes | Data Base |
| | DIRECT | | | |
| | CURRENT | | | |
| | SERIAL | | | |
| | RSERIAL | | | |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | | No | No Lock |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | No | Yes | Data Set |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | | No | No Lock |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| DELETE | CHAIN | Yes | Yes | Data Base |
| REPLACE | RCHAIN | | | |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | | No | Data Base |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | No | Yes | Entry/Set* |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | | No | Entry/Set* |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | None | Yes | Yes | Data Base |
| | DIRECT | | | |
| | CURRENT | | | |
| | SERIAL | | | |
| | RSERIAL | | | |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | | No | Data Base |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | No | Yes | Data Set |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | | No | Data Set |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| PUT | None | Not Applicable | Yes | Data Set |
| UPDATE | | | | |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | | No | Data Set |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| GET | CHAIN | Not Applicable | Yes | Entry |
| | RCHAIN | | | |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | | No | No Lock |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | None | Not Applicable | Yes | Data Set |
| | DIRECT | | | |
| | CURRENT | | | |
| | SERIAL | | | |
| | RSERIAL | | | |
| | | | | |
-----------------------------------------------------------------------------------------------------
| | | | | |
| | | | No | No Lock |
| | | | | |
-----------------------------------------------------------------------------------------------------
* The REPLACE verb locks at the entry level with the UPDATE option and at
the set level without the UPDATE option.
Using the LOCK Option with the Database Access Verbs
The LOCK option applies to all database access verbs, which include
DELETE, FIND, GET, OUTPUT, PUT, REPLACE, and UPDATE. The LOCK option can
be used to override the SET(OPTION) NOLOCK statement for any specific
verb. Tables 6-2 and 6-3 show how locking is applied with the possible
combinations of locking methods for database and MPE and KSAM files,
respectively. See the description of the individual verbs in Chapter 8
for more information. There is also a LOCK option that applies to the
LOGTRAN verb, which is discussed in the next subsection.
Table 6-2 Understanding Database Locking
--------------------------------------------------------------------------------------------------------
| | |
| Automatic Locking | Transact Verbs |
| Combined With: | |
| | |
--------------------------------------------------------------------------------------------------------
| | | | | | | | |
| | FIND | OUTPUT | GET | PUT | DELETE | UPDATE | REPLACE |
| | | | | | | | |
| No options | A | A | A | B* | C* | B* | C* |
| | | | | | | | |
--------------------------------------------------------------------------------------------------------
| | | | | | | | |
| LOCK option | B | B | B | B | B | B | B |
| | | | | | | | |
--------------------------------------------------------------------------------------------------------
| | | | | | | | |
| LOCK option and | B | B | B | B | B | B | B |
| SET(OPTION) NOLOCK | | | | | | | |
| | | | | | | | |
--------------------------------------------------------------------------------------------------------
| | | | | | | | |
| SET(OPTION) NOLOCK only | A | A | A | A | A | A | A |
| | | | | | | | |
--------------------------------------------------------------------------------------------------------
A = No locks
B = Lock for the entire verb
C = Lock and unlock for each record retrieved
* = Lock if database opened with mode 1; otherwise no locks
Table 6-3 Understanding KSAM and MPE File Locking
--------------------------------------------------------------------------------------------------------
| | |
| Automatic Locking | Transact Verbs |
| Combined With: | |
| | |
--------------------------------------------------------------------------------------------------------
| | | | | | | | |
| | FIND | OUTPUT | GET | PUT | DELETE* | UPDATE | REPLACE |
| | | | | | | | |
| No options | C | C | C | C | C | C | C |
| | | | | | | | |
--------------------------------------------------------------------------------------------------------
| | | | | | | | |
| LOCK option | B | B | B | B | B | B | B |
| | | | | | | | |
--------------------------------------------------------------------------------------------------------
| | | | | | | | |
| LOCK option and | B | B | B | B | B | B | B |
| SET(OPTION) NOLOCK | | | | | | | |
| | | | | | | | |
--------------------------------------------------------------------------------------------------------
| | | | | | | | |
| SET(OPTION) NOLOCK only | A | A | A | A | A | A | A |
| | | | | | | | |
--------------------------------------------------------------------------------------------------------
| | | | | | | | |
| SET(OPTION) NOLOCK and | A | A | A | A | A | A | A |
| LOCK option on SYSTEM | | | | | | | |
| statement | | | | | | | |
| | | | | | | | |
--------------------------------------------------------------------------------------------------------
A = No locks
B = Lock for the entire verb
C = If lock is specified in SYSTEM statement, lock and unlock for
each record retrieved
* = Delete not allowed on an MPE file
Using the LOCK Option with the LOGTRAN Statement
Locking across a transaction can be handled by transaction-level locking
executed when you specify the LOCK option on the LOGTRAN statement.
Transaction locking can be used with or without database logging. The
syntax is:
LOGTRAN(BEGIN) base,log-message[,option-list];
where option-list includes the LOCK option in the following format:
LOCK(setname[(cond)][,setname[(cond)]]...)
You specify setname as a list of data set names separated by commas or as
a @ sign to specify that the entire database (such as the base specified
in the SYSTEM statement) is locked. You can also specify a lock
condition parameter, cond, which can be COND or UNCOND, representing
conditional or unconditional locking, respectively. The default is
conditional locking. The data sets specified are locked at the set level
when Transact encounters the LOGTRAN(BEGIN) or LOGTRAN(XBEGIN)
statements. The data sets are unlocked when Transact encounters a
corresponding LOGTRAN(END), LOGTRAN(XEND), or LOGTRAN(XUNDO) statement
with the same database name (same database access path).
When using the LOCK option on the LOGTRAN statement, you should also
specify the SET(OPTION) NOLOCK statement to ensure that automatic locking
is not activated for any database access verbs within your transaction.
The SET(OPTION) NOLOCK statement does not affect transaction locking. To
re-activate automatic locking, use the RESET(OPTION) LOCK statement. In
the example shown here, transaction level locking is used to lock two
data sets in two different databases. Transaction locking is also used
in the second version of the subsequent example.
SYSTEM LOCKS,BASE=BASE1(";"),BASE2(";");
DEFINE(ITEM) X1 X(10):
X2 X(10);
SET(OPTION) NOLOCK;
PROMPT X1:X2;
LOGTRAN(BEGIN) $HOME," Lock Base1 Set ",LOCK(Base1master);
LOGTRAN(BEGIN) BASE2," Lock Base2 Set ",LOCK(Base2master);
PUT Base1master,LIST=(X1);
PUT Base2master,LIST=(X2);
LOGTRAN(END) BASE2," Unlock Base2 Set ";
LOGTRAN(END) $HOME," Unlock Base1 Set ";
EXIT;
MPE/iX 5.0 Documentation