테마
5월 20일(월) 10:04에 정산팀 전체의 정산 등록 화면이 저장 버튼에서 멈췄다. 박팀장은 "배포한 사람 없대요." 하고 전했다. 화면은 10:14에 저절로 풀렸다.
지난 금요일 18:40에 개발팀이 '정산번호 중복 버그 수정' 핫픽스를 반영했다. 정산 번호를 MAX+1 대신 채번 테이블에서 받도록 바꾼 것이다. 10:04에는 정산 보정 배치가 정산 30건을 등록하고 있었다(배치는 30건을 다 등록한 뒤 COMMIT하며, 약 10분 걸린다).
강도현이 2019.03에 남긴 커밋 메모는 이렇다. "시퀀스는 쓰지 않음. 결번이 생긴다(2018 감사 지적)."
T_ORD_STLM 정산: 100,000행 · 640블록 · 정산 번호 STLM_SEQ는 100,000까지 쓰였다 · PK 없음 · 인덱스 없음T_STLM_NUM 채번: 1행 · PK (NUM_TP) · 핫픽스 전에는 쓰지 않던 테이블-- PKG_ORD_STLM.REG_STLM — 정산 한 건 등록 (화면 · 보정 배치가 같이 부른다)
-- 5월 17일 핫픽스 "정산번호 중복 버그 수정"
-- 이전 판 (2019.03 강도현) : SELECT NVL(MAX(STLM_SEQ), 0) + 1 INTO v_no FROM T_ORD_STLM;
SELECT LAST_NO + 1 INTO v_no
FROM T_STLM_NUM
WHERE NUM_TP = 'STLM'
FOR UPDATE;
UPDATE T_STLM_NUM SET LAST_NO = v_no WHERE NUM_TP = 'STLM';
INSERT INTO T_ORD_STLM (STLM_SEQ, ORD_SEQ, CUS_ID, STLM_DT, STLM_AMT)
VALUES (v_no, :ord_seq, :cus_id, SYSDATE, :amt);
-- COMMIT 은 부른 쪽이 한다 — 화면은 저장 버튼에서 · 보정 배치는 30 건을 다 등록한 뒤
[세 사람 동시 — 핫픽스 판 · 연습 DB 복사본 (배치가 번호를 받고 약 3초 뒤 COMMIT 하도록 줄였다)]
시각 배치 (SID 53) 화면 1 (SID 21) 화면 2 (SID 216)
t+0.0 번호 받기 → 100001 · 등록을 이어 간다
t+0.1 번호 받기 → 기다림
t+0.1 번호 받기 → 기다림
t+3.2 COMMIT → 100002 (기다림 316 cs) → 100003 (321 cs)
[V$LOCK — 기다리는 동안]
SID TYPE 대상 / 이름표 LMODE REQUEST BLOCK
53 TM T_STLM_NUM 3 0 0
53 TX TX-00050011-00000338 (배치의 것) 6 0 1
21 TM T_STLM_NUM 3 0 0
21 TX TX-00050011-00000338 0 6 0
216 TM T_STLM_NUM 3 0 0
216 TX TX-00050011-00000338 0 6 0
[블로킹 트리 — V$SESSION (연습에서는 배치의 '일' 을 잠깐 쉬는 것으로 흉내 냈다)]
SID_TREE EVENT SECS BLOCKER
53 PL/SQL lock timer 0
21 enq: TX - row lock contention 2 53
216 enq: TX - row lock contention 2 53
[이전 판 MAX+1 — 같은 세 사람]
번호 하나 Buffers 568 (TABLE ACCESS FULL T_ORD_STLM) · 기다림 0 ~ 1 cs · 셋 다 100001 (겹침)
MAX+1 에 PK 를 걸면 — 화면 둘이 TX 를 REQUEST 4 로 220 cs 기다린 뒤 ORA-00001
V$LOCK을 보고 누가 무엇을 잠가서 누구를 언제까지 막는지 설명하시오. 운영에서 화면이 10분 동안 멈춘 이유도 쓰시오.