如何得知某一物件被某些 Job 鎖住?(API QWCLOBJL)
傳統上可以透過 WRKOBJLCK 指令查到, 但要於程式中直接取得相關資訊就不容易,
因為需要將 WRKOBJLCK OBJ(xxx/xxx) OBJTYPE(XXX) OUTPUT(*PRINT) 輸出至報表,
再將報表複製至 PF 中,再由程式讀取內容解析相關資訊, 過於麻煩.
我們可以利用系統 API QWCLOBJL 直接取得是哪一作業鎖住物件,並做相對應的動作,
如傳送訊息給鎖住物件的作業, 要該作業退出系統,甚至直接 ENDJOB 終止該作業.
此範例僅發送訊息給該作業的使用者.
File : QCLSRC
Member: CHKOBJLCKC
Type : CLP
Usage : CRTCLPGM CHKOBJLCKC
CALL CHKOBJLCKC ('object-name' 'object-library' 'object-type' 'member-name')
只有針對 PF 的 member 時,才需要指定 membername, 其他物件只要給空白即可.
PGM PARM(&OBJ &LIB &OBJTYPE &MBRNAME)
DCL VAR(&OBJ) TYPE(*CHAR) LEN(10)
DCL VAR(&LIB) TYPE(*CHAR) LEN(10)
DCL VAR(&OBJTYPE) TYPE(*CHAR) LEN(10)
DCL VAR(&MBRNAME) TYPE(*CHAR) LEN(10)
DCL VAR(&USRSPC) TYPE(*CHAR) LEN(20)
DCL VAR(&EXTATR) TYPE(*CHAR) LEN(10)
DCL VAR(&INITSIZE) TYPE(*CHAR) LEN(4)
DCL VAR(&INITVALUE) TYPE(*CHAR) LEN(1)
DCL VAR(&PUBAUTH) TYPE(*CHAR) LEN(10)
DCL VAR(&TEXT) TYPE(*CHAR) LEN(50)
DCL VAR(&ERRCODE) TYPE(*CHAR) LEN(8)
DCL VAR(&QUALOBJ) TYPE(*CHAR) LEN(20)
DCL VAR(&POS) TYPE(*CHAR) LEN(4)
DCL VAR(&LEN) TYPE(*CHAR) LEN(4)
DCL VAR(&TEMP) TYPE(*CHAR) LEN(4)
DCL VAR(&OFFSET) TYPE(*DEC) LEN(10 0)
DCL VAR(&ENTCOUNT) TYPE(*DEC) LEN(10 0)
DCL VAR(&ENTSIZE) TYPE(*DEC) LEN(10 0)
DCL VAR(&ENTRY) TYPE(*CHAR) LEN(64)
DCL VAR(&JOB) TYPE(*CHAR) LEN(10)
DCL VAR(&USER) TYPE(*CHAR) LEN(10)
DCL VAR(&JOBNBR) TYPE(*CHAR) LEN(6)
DCL VAR(&LOCKSTATE) TYPE(*CHAR) LEN(10)
DCL VAR(&LOCKSTATUS) TYPE(*DEC) LEN(10 0)
DCL VAR(&LOCKTYPE) TYPE(*DEC) LEN(10 0)
DCL VAR(&MBRNAME) TYPE(*CHAR) LEN(10)
DCL VAR(&SHARE) TYPE(*CHAR) LEN(1)
DCL VAR(&SCOPE) TYPE(*CHAR) LEN(1)
DCL VAR(&THREAD) TYPE(*CHAR) LEN(8)
/********************************************************** +
* CREATE A USER SPACE TO STORE THE LIST OF JOBS THAT ARE +
* LOCKING AN OBJECT. +
************************************************************/
CHGVAR VAR(%BIN(&INITSIZE)) VALUE(65536)
CHGVAR VAR(&INITVALUE) VALUE(X'00')
CHGVAR VAR(&USRSPC) VALUE('OBJLOCKS QTEMP')
CHGVAR VAR(&EXTATR) VALUE('MYPGM')
CHGVAR VAR(&PUBAUTH) VALUE('*EXCLUDE')
CHGVAR VAR(&TEXT) VALUE('USER SPACE TO CONTAIN OUTPUT +
FROM QWCLOBJL API')
CHGVAR VAR(%BIN(&ERRCODE 1 4)) VALUE(0)
CALL PGM(QUSCRTUS) PARM(&USRSPC +
&EXTATR +
&INITSIZE +
&INITVALUE +
&PUBAUTH +
&TEXT +
'*YES' +
&ERRCODE )
/********************************************************** +
* TELL THE QWCLOBJL API TO PUT A LIST OF LOCKS FOR THE +
* GIVEN OBJECTS INTO THE USER SPACE +
************************************************************/
CHGVAR VAR(&QUALOBJ) VALUE(&OBJ *CAT &LIB)
CHGVAR VAR(%BIN(&ERRCODE 1 4)) VALUE(0)
CALL PGM(QWCLOBJL) PARM(&USRSPC +
'OBJL0100' +
&QUALOBJ +
&OBJTYPE +
&MBRNAME +
&ERRCODE )
/********************************************************** +
* RETRIEVE INFORMATION ABOUT WHERE THE LIST ENTRIES ARE +
* LOCATED IN THE USER SPACE +
* +
* POSITION 125-128 = OFFSET TO THE LIST DATA +
* 133-136 = NUMBER OF ENTRIES IN LIST +
* 137-140 = SIZE OF EACH LIST ENTRY +
************************************************************/
CHGVAR VAR(%BIN(&POS)) VALUE(125)
CHGVAR VAR(%BIN(&LEN)) VALUE(4)
CALL PGM(QUSRTVUS) PARM(&USRSPC &POS &LEN &TEMP)
CHGVAR VAR(&OFFSET) VALUE(%BIN(&TEMP))
CHGVAR VAR(%BIN(&POS)) VALUE(133)
CALL PGM(QUSRTVUS) PARM(&USRSPC &POS &LEN &TEMP)
CHGVAR VAR(&ENTCOUNT) VALUE(%BIN(&TEMP))
CHGVAR VAR(%BIN(&POS)) VALUE(137)
CALL PGM(QUSRTVUS) PARM(&USRSPC &POS &LEN &TEMP)
CHGVAR VAR(&ENTSIZE) VALUE(%BIN(&TEMP))
/********************************************************** +
* READ THE LIST OF ENTRIES FROM THE USER SPACE +
************************************************************/
CHGVAR VAR(%BIN(&POS)) VALUE(1 + &OFFSET)
CHGVAR VAR(%BIN(&LEN)) VALUE(64) /* SIZE OF &ENTRY VAR */
LOOP: IF (&ENTCOUNT *GT 0) DO
/* READ A SINGLE ENTRY FROM THE USER SPACE */
CALL PGM(QUSRTVUS) PARM(&USRSPC &POS &LEN &ENTRY)
CHGVAR VAR(&JOB) VALUE(%SST(&ENTRY 1 10))
CHGVAR VAR(&USER) VALUE(%SST(&ENTRY 11 10))
CHGVAR VAR(&JOBNBR) VALUE(%SST(&ENTRY 21 6))
CHGVAR VAR(&LOCKSTATE) VALUE(%SST(&ENTRY 27 10))
CHGVAR VAR(&LOCKSTATUS) VALUE(%BIN(&ENTRY 37 4))
CHGVAR VAR(&LOCKTYPE) VALUE(%BIN(&ENTRY 41 4))
CHGVAR VAR(&MBRNAME) VALUE(%SST(&ENTRY 45 10))
CHGVAR VAR(&SHARE) VALUE(%SST(&ENTRY 55 1))
CHGVAR VAR(&SCOPE) VALUE(%SST(&ENTRY 56 1))
CHGVAR VAR(&THREAD) VALUE(%SST(&ENTRY 57 8))
/* AT THIS POINT, THE FIELDS ABOVE SHOULD BE CORRECT +
FOR ONE OF THE JOBS IN THE LIST. YOU CAN NOW +
ISSUE A SNDMSG, SNDBRKMSG OR ENDJOB AS NEEDED */
/* FOR EXAMPLE: */
SNDMSG MSG('YOU HAVE 5 SECONDS TO GET OUT OF THAT +
PROGRAM, BUDDY.') TOUSR(&USER)
SNDPGMMSG MSG( &JOBNBR *CAT '/' *CAT +
&USER *TCAT '/' *CAT +
&JOB *BCAT 'LOCK OBJECT' *BCAT +
&LIB *TCAT '/' *CAT +
&OBJ *BCAT '.')
/* ENDJOB JOB(&JOBNBR/&USER/&JOB) OPTION(*CNTRLD) DELAY(5) */
/* MONMSG MSGID(CPF1362 CPF1363) */
/* ADVANCE TO NEXT ENTRY IN LIST */
CHGVAR VAR(%BIN(&POS)) VALUE(%BIN(&POS) + &ENTSIZE)
CHGVAR VAR(&ENTCOUNT) VALUE(&ENTCOUNT - 1)
GOTO LOOP
ENDDO
/* DELETE THE USER SPACE, WE'RE DONE! */
CALL PGM(QUSDLTUS) PARM(&USRSPC &ERRCODE)
ENDPGM
A blog about IBM i (AS/400), MQ and other things developers or Admins need to know.
星期二, 11月 07, 2023
2005-08-19 如何得知某一物件被某些 Job 鎖住?(API QWCLOBJL)
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言