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

매달 1일 오전 월 마감 확정을 하는 20분 동안 쇼핑몰 주문이 한 건도 들어오지 않는다

중급PLSQL한빛유통542 / 700

상황 ​

한빛유통 정산팀은 매달 1일 10:00에 지난달 주문을 정산으로 옮기는 「월 마감 확정」을 한다. 2021년에 오과장이 만든 절차서대로 SQL Developer에서 문장을 하나씩 돌리고, 회계팀이 금액을 확인해 주면 COMMIT한다. 확인까지 보통 20분이 걸린다. 11월 1일에는 10:01부터 10:23까지 쇼핑몰의 주문 등록과 결제 완료가 모두 멈췄다. 박팀장의 말이다. "매달 1일 오전마다 주문이 0건인 20분이 있었다는데, 다들 원래 그런 줄 알았대요."

테이블과 인덱스 ​

  • T_ORD 주문: 100,000행 · 896블록 · PK_T_ORD (ORD_SEQ) · 정산 표시 컬럼 STLM_YN(문제 설정, 기본 'N') · 지난달 COMPLETE 주문은 약 2,500건이다
  • 낮에는 주문 등록(INSERT)과 결제 완료(UPDATE, ORD_ST PENDING → COMPLETE)가 초당 몇 건씩 들어온다. 지난달 PENDING 주문도 이달 초에 결제가 끝나면 COMPLETE가 된다
  • T_ORD_STLM 정산: PK_T_ORD_STLM (STLM_SEQ) · 정산 번호는 시퀀스 SQ_STLM_SEQ로 받는다
  • 절차서 첫 줄의 주석: "INSERT와 UPDATE 사이에 결제가 끝난 주문이 정산 없이 Y로 바뀐 사고(2021.02)가 있었다. 마감 중에는 주문을 잠근다."

원본 SQL ​

sql
-- 월 마감 확정 절차서 (2021.03 오과장) · SQL Developer 에서 한 문장씩
LOCK TABLE T_ORD IN SHARE MODE;                          -- 마감 중에는 주문을 잠근다 (2021.02 사고)

INSERT INTO T_ORD_STLM (STLM_SEQ, ORD_SEQ, CUS_ID, STLM_DT, STLM_AMT)
SELECT SQ_STLM_SEQ.NEXTVAL, ORD_SEQ, CUS_ID, SYSDATE, ORD_AMT
  FROM T_ORD
 WHERE ORD_DT >= :m_from AND ORD_DT < :m_to
   AND ORD_ST = 'COMPLETE' AND STLM_YN = 'N';

UPDATE T_ORD SET STLM_YN = 'Y'
 WHERE ORD_DT >= :m_from AND ORD_DT < :m_to
   AND ORD_ST = 'COMPLETE' AND STLM_YN = 'N';

-- 건수 · 금액 대사 쿼리 몇 개 → 회계팀 확인 (보통 20분)
COMMIT;

실행계획 학습용 예시 · TM 호환성은 교재 12화 실측(실습/01 [D]) ​

xplan
[11월 1일 — 시간표]
시각        정산 담당 (SID 118)                      쇼핑몰 (WAS 세션들)
10:01:40    LOCK TABLE T_ORD IN SHARE MODE           진행 중이던 결제 2건이 끝날 때까지 0.8초 기다림 (그동안 들어온 요청은 그 뒤에 섬)
10:01:41    → 잡음 (TM 4)                             이 순간부터 주문 등록 · 결제 완료가 하나씩 멈춤
10:02:05    INSERT … 2,512 rows · UPDATE … 2,512 rows
10:02 ~     대사 쿼리 · 회계팀에 메일 · 답을 기다림
10:23:17    COMMIT                                   멈췄던 요청이 한꺼번에 진행 · 그사이 WAS 타임아웃으로 실패한 주문 341건

[V$LOCK — 10:10:00 · T_ORD]
SID        TYPE  대상              LMODE  REQUEST  BLOCK
118        TM    T_ORD               4       0       1
118        TX    118 의 트랜잭션      6       0       0
(WAS 76개)  TM    T_ORD               0       3       0      ← 주문 등록 INSERT · 결제 완료 UPDATE

[V$SESSION — 같은 시각]
118         SQL*Net message from client    478초       (회계팀 답을 기다리는 중)
WAS 76개    enq: TM - contention           1 ~ 479초   BLOCKING_SESSION 118

[ASH · 매달 1일 오전 enq: TM - contention 이 이어진 시간]   9월 18분 · 10월 23분 · 11월 21분

문제 ​

  1. 시간표와 V$LOCK을 근거로 정산 담당 한 사람이 쇼핑몰 주문 전체를 세운 이유를 TM 모드로 설명하시오.
  2. 2021년의 사고를 막으면서도 테이블을 잠그지 않도록 마감 절차를 고치시오.
  3. 회계팀 확인 20분을 트랜잭션 안에 두지 않으려면 어떻게 할지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자