On 13-Dec-2013 15:06 -0800, Horn, Jim wrote:
In a cl program, I am issuing the following command to lock a member
in a file. In case it matters the srctype of the file is TXT.
ALCOBJ OBJ((&LIBRARY/QTXTSRC *FILE *EXCL &PROGNAME)) WAIT(&WAIT)
If the member is already locked, then the test fails and we have to
release the lock on the member before continuing. All well and good.
If the lock [aka: allocate] fails; with the CPF1002? If so, then no
lock exists to be released. No action regarding locking is required;
optionally, the allocation can be re-attempted, but no unlocking by the
program[mer]\user should occur in response to the CPF1002 exception
Later I issue
DLCOBJ OBJ((&LIBRARY/QTXTSRC *FILE *EXCL &PROGNAME))
/* no monmsg after */
no errors, nothing in the joblog, but the member remains locked.
Work with Member Locks
File . . . . . : QTXTSRC Type . . . . . : PHY
Library . . : INTQAT ASP device . . : *SYSBAS
Opt Member Job User Type Lock Status Share
JDCPKKKK QCTLD1 JHORN MBR *SHRRD HELD
DATA *EXCL HELD
The lock is not released until I sign off the workstation. As if I
had not issued the DLCOBJ command at all.
No mention of release... to improve the possibility of a defect search.
Was debug and/or CLP command logging used to verify that the specific
and expected DLCOBJ ran? And matching exactly to the ALCOBJ?
Unlikely, because an open should not have the *EXCL data lock.
But... Is it possible that the locks exist implicitly due to an /open/
instead of the /allocate/ activity? Check WRKJOB OPTION(*OPNF) to see
if the file is opened. The file.mbr would be closed and the lock
disappear at signoff. There is a RCDFMTLCK parameter on OVRDBF that
enables the noted DATA lock, but I seem to recall that there would be
*two* DATA locks; i.e. one *SHRRD and then another *EXCL to implement
the so-called Record Format Lock.
If [as I suspect probably] not per the database file member being
open in the job:
Do the values of either of the variables (&LIBRARY) and (&PROGNAME)
ever change anywhere in the program. Is there ever a Rename Member
(RNMM) done in the program? Or less likely, a Rename Object (RNMOBJ) or
Move Object (MOVOBJ) against the *FILE object? An effective RNMLIB
request? The above output was apparently from a request to WRKOBJLCK
INTQAT/QTXTSRC MBR(*ALL), but what does that request with MBR(*NONE)
show? If the MBR(*NONE) invocation shows "(There are no locks for the
specified object)" and a message "Press F6 to see member locks.", then
the lock\unlock requests presumably were unpaired.
Unfortunately the onus is on the programmer\user to deallocate
exactly what was allocated; i.e. the Allocate Object (ALCOBJ) and
Deallocate Object (DLCOBJ) request must be *identically paired*
according to *effect* not according to the *values* specified on the
parameters. That means the object named on each request must be the
*same* object according to its permanent address, not according to its
current name. And because the attempt to deallocate a member that is
not allocated generates no error whatsoever, the ability to track the
origin of an error is muddled. And worse, if the requests are unpaired
against the *same* file, then the *SHRRD lock on the *FILE object is
lost, and that breaks the locking protocol for a database file... which
can cause assumptions by the OS DataBase (DB) code to fail. While
harsh, that has always been considered a permanent restriction and a
usage error if encountered.