테마
본사 레거시 유통의 「입고 예정」 배치는 매일 08:00에 오늘 입고될 발주(거래처 리드타임 2일, 이틀 전에 낸 발주)를 발주완료(10)에서 입고중(11)으로 바꾼다. 물류센터 화면은 입고중인 발주만 보여 준다.
2022년에 이 배치가 발주 담당자의 수정 화면을 기다리느라 40분 멈춘 일이 있었고, 그 뒤 배치에 SKIP LOCKED를 넣었다. 지난달부터 물류센터가 "트럭이 왔는데 화면에 없는 발주"라며 입고를 일주일에 한두 번 돌려보낸다. 배치 로그는 매번 '성공'이다.
CF12 발주: 734행 · 10블록 · PK ORD_NO ('2023061002') · ORD_DT VARCHAR2(8) · ORD_PRGS_CD (CF16 공통코드: 10 발주완료 · 11 입고중 · 12 입고완료) · 하루 입고 예정 3~8건CF13 발주상품: 7,102행 · 57블록 · PK (ORD_NO, ITM_NO)CF12 행을 FOR UPDATE로 잠그고, 수량을 고쳐 저장할 때 COMMIT한다. 아침 08:00 전후에 전날까지의 발주를 다듬는 일이 잦다.-- 08:00 「입고 예정」 배치
DECLARE
v_cnt PLS_INTEGER := 0;
BEGIN
FOR r IN (SELECT ORD_NO
FROM CF12
WHERE ORD_DT = TO_CHAR(SYSDATE - 2, 'YYYYMMDD')
AND ORD_PRGS_CD = '10'
FOR UPDATE SKIP LOCKED) LOOP -- 2022.04 수정 화면을 기다리지 않게
UPDATE CF12 SET ORD_PRGS_CD = '11', MOD_DTT = SYSDATE WHERE ORD_NO = r.ORD_NO;
v_cnt := v_cnt + 1;
END LOOP;
COMMIT;
PKG_LOG.WRITE('입고 예정 ' || v_cnt || '건 성공');
END;
[시간표 — 6월 12일 · 6월 10일에 낸 발주 6건]
시각 발주 담당자 화면 (SID 66) 입고 예정 배치 (SID 140)
07:52 발주 2023061002 열기 → CF12 행 잠금 (FOR UPDATE)
수량 다듬는 중 — COMMIT 전
08:00:00 대상 6건 중 잠기지 않은 5건만 가져온다 (2023061002 는 에러 없이 건너뜀)
08:00:01 5건 → 11 · COMMIT · 로그 '입고 예정 5건 성공'
08:09 저장 · COMMIT (2023061002 는 여전히 10 발주완료)
10:40 트럭 도착 · 물류센터 화면에 2023061002 없음 → 입고 거부
[V$LOCK — 08:00:00]
SID TYPE 대상 LMODE REQUEST BLOCK
66 TM CF12 3 0 0
66 TX SID 66 의 트랜잭션 6 0 0 ← 기다리는 사람이 없어 BLOCK 0
140 TM CF12 3 0 0
140 TX SID 140 의 트랜잭션 6 0 0
(배치는 아무것도 기다리지 않았다 · enq: TX 0)
[같은 대상 — 배치 전후 건수]
ORD_PRGS_CD = '10' ORD_PRGS_CD = '11'
08:00 전 6 0
08:00 후 1 5 ← 로그에는 '5건 성공'뿐, 몇 건이 남았는지는 없다
[지난 4주 — 입고를 돌려보낸 발주] 7건 · 모두 배치 시각에 발주 수정 화면이 열려 있던 발주
SKIP LOCKED가 맞는 일과 맞지 않는 일을 구분해 쓰시오.