Alan Campin wrote:
<<SNIP>>
1. Triggers put an exclusive lock on the trigger program. It
cannot be removed except by removing the trigger from the table.
If errors are detected in the trigger program, they cannot be
corrected without removing the table from triggers.
I believe the lock on the trigger program is *SHRRD, which
prevents any other thread or process from getting an exclusive lock.
Thus for example, a request to RNMOBJ TheTrgPgm *PGM AltPgmName
will fail, because it is the _rename_ activity which requires [and
if not precluded by any held locks, will establish] an exclusive lock.
2. Triggers put an exclusive lock on tables when they are under
trigger control. They cannot be deleted or changed while under
trigger control. <<SNIP>>
It is the /open/ that locks the file, and that lock is *SHRRD on
the *FILE, which prevents other activity that requires exclusive use
of the *FILE object. The *SHRRD lock occurs regardless of whether a
trigger is defined on the file or not. The record locks [except
read triggers] are a side-effect of the I/O rather than the trigger;
i.e. for update and isolation level may both impact other readers &
update requesters. Any additional object locks effected by the
trigger being activated could not be exclusive, since that would
mean only one process could access the file at any one time; i.e.
exclusive locks would then disallow concurrent open\access to any
file with a trigger. Certainly that is not an issue. So it is the
fact that the file is open [alone, or in combination with whatever
additional locks are applied at open time for the triggers] which
prevents ADDPFTRG & RMVPFTRG activity. And it is the remove and add
trigger activity which require and will obtain their own exclusive
locks [like rename object, noted above], which conflicts with any
[even *SHRRD] locks held by another process\thread.
Script to see & compare locking difference for when trigger is
established on a file:
/* setup part 1; create a file */
create table mylib.mytrgxmp (c char)
/* wrkobjlck for no trigger */
opndbf mylib/mytrgxmp *inp opnid(opninp)
wrkobjlck mylib/mytrgxmp *file mbr(myrtgxmp)
wrkobjlck qcmd *pgm
clof opninp
opndbf mylib/mytrgxmp *all opnid(opnall)
wrkobjlck mylib/mytrgxmp *file mbr(myrtgxmp)
wrkobjlck qcmd *pgm
clof opnall
/* setup part 2; add a trigger */
addpftrg mylib/mytrgxmp pgm(qcmd) trgevent(*ins)
/* wrkobjlck with trigger */
opndbf mylib/mytrgxmp *inp opnid(opninp)
wrkobjlck mylib/mytrgxmp *file mbr(myrtgxmp)
wrkobjlck qcmd *pgm
clof opninp
opndbf mylib/mytrgxmp *all opnid(opnall)
wrkobjlck mylib/mytrgxmp *file mbr(myrtgxmp)
wrkobjlck qcmd *pgm
clof opnall
The locks for both open identifiers OPNINP will be the same.
Although the open identifier OPNALL for the /with trigger/ example
may effect more or greater locks on the file [I do not recall it
will] than for the /no trigger/ example, it is still just the locks
for the open itself which prevent the add\rmv requests in another
process\thread. Note: the use of QCMD in the script is of course
bogus, but its use is sufficient to run the script without any
actual requirement to create a valid trigger program.
Regards, Chuck
As an Amazon Associate we earn from qualifying purchases.