如何得知某一物件被某些 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)
 
沒有留言:
張貼留言