Skip to content
튜닝 연습Lock과 동시성 제어
LOCK-026

정산 금액 저장 버튼 하나가 정산 시스템 화면 전체를 멈춘다

기초SELECT한빛유통521 / 700

상황 ​

정산팀 조민우는 「정산 금액 정정」 화면에서 정산 한 건의 금액을 고친다. 화면은 저장할 때 그 행을 FOR UPDATE로 잠그고, 금액이 그사이 바뀌지 않았는지 확인한 뒤 고친다. 월요일 10:30에 저장 버튼이 응답하지 않아 조민우와 동료들이 몇 번씩 다시 눌렀다. 10:34에는 정산 조회 화면과 로그인까지 멈췄고, 10:36에 매주 도는 「정산 재계산」 배치가 끝나자 모두 풀렸다.

테이블과 인덱스 ​

  • T_ORD_STLM 정산: 100,000행 · 640블록 · PK_T_ORD_STLM (STLM_SEQ)(12화 재발방지로 추가)
  • 「정산 재계산」 배치: 매주 월요일 10:30에 지난주 정산 약 2만 건의 금액을 한 문장 UPDATE로 다시 계산하고 COMMIT한다(약 6분).
  • 정산 시스템 WAS의 커넥션 풀은 40개다. 요청은 커넥션을 얻은 뒤 응답을 돌려줄 때 반납한다. 웹 화면은 응답이 오지 않아도 버튼을 다시 누를 수 있다.

원본 SQL ​

sql
-- 「정산 금액 정정」 저장
SELECT STLM_AMT
  FROM T_ORD_STLM
 WHERE STLM_SEQ = :stlm_seq
   FOR UPDATE;                               -- 화면에서 읽은 금액과 같은지 확인한다

UPDATE T_ORD_STLM
   SET STLM_AMT = :new_amt
 WHERE STLM_SEQ = :stlm_seq;
COMMIT;

실행계획 학습용 예시 ​

xplan
[시간표 — 월요일]
시각         누가                         무엇을
10:30:00     정산 재계산 배치 (SID 53)     UPDATE 시작 · 지난주 정산 20,114행을 차례로 잠근다 (COMMIT 은 문장이 끝난 뒤)
10:30:40     조민우                        정산 96,211 (지난주 건) 저장 → FOR UPDATE 에서 기다림
10:30:55     조민우                        응답이 없어 다시 누름 → 새 요청 · 새 커넥션 · 같은 행에서 기다림
10:31 ~ 34   동료 다섯 명                   저장 · 다시 누르기 → 저장 요청 38개가 커넥션 38개를 쥔 채 기다림
10:34:10     정산 WAS                      커넥션 풀 40개 모두 사용 → 조회 화면 · 로그인도 커넥션을 기다림
10:36:12     배치                          COMMIT → 기다리던 요청 38개가 차례로 진행

[V$SESSION — 10:34:30 · 정산 WAS 세션]
EVENT                            세션 수   BLOCKING_SESSION   하고 있는 문장
enq: TX - row lock contention       38     53                SELECT STLM_AMT FROM T_ORD_STLM WHERE STLM_SEQ = :B1 FOR UPDATE
SQL*Net message from client          2                        (방금 응답을 돌려준 조회 화면)
(SID 53 — 배치 · db file scattered read)

[V$LOCK — 같은 시각 · 기다리는 세션 하나]
SID   TYPE  대상                    LMODE  REQUEST  BLOCK
53    TX    배치의 트랜잭션            6      0        1
118   TM    T_ORD_STLM                3      0        0
118   TX    배치의 트랜잭션            0      6        0

[WAS 로그]  10:34:10 ~ 10:36:12 커넥션 대기 타임아웃 412건 (정산 조회 · 로그인 · 정산 정정)

문제 ​

  1. 시간표와 V$SESSION을 근거로 정산 몇 건의 저장 요청이 어떻게 정산 시스템 화면 전체를 멈추게 했는지 설명하시오.
  2. 저장이 한없이 기다리지 않도록 SQL을 고치고, 화면이 그 에러를 어떻게 처리할지 쓰시오. NOWAIT와 WAIT n 중 무엇을 고를지도 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자