테마
고객이 상품평가를 등록하면 화면은 평가(T_ITM_EVL)를 넣은 뒤 상품별 평가 요약(T_ITM_EVL_SUM)을 고치는 프로시저 ADD_EVL_SUM을 부르고, 둘을 한 번에 커밋한다. 평가는 하루 1만 건쯤 들어온다.
지난 화요일 10:00에 신상품 8개를 출시했는데, 10:00 ~ 10:02 사이에 평가 등록 3건이 ORA-00001로 실패해 고객 화면에 '등록 실패'가 떴다. 개발팀은 MERGE로 바꾸면 해결된다고 한다. 박팀장은 방법별 비교와 근거를 요청했다.
T_ITM_EVL 상품평가: 5,000행 · 48블록 · PK_T_ITM_EVL (ITM_ID, EVL_LST_NO)T_ITM_EVL_SUM(상품별 평가 요약, 이 문제를 위해 둔 테이블): 상품 100개 + 신상품 8개 · PK (ITM_ID) · EVL_CNT, EVL_PT_SUM, LAST_EVL_DT · 상품의 첫 평가가 들어올 때 행이 생긴다M_ITM 상품: 100행(출시 뒤 108행) · PK_M_ITMPROCEDURE ADD_EVL_SUM(p_itm VARCHAR2, p_pt NUMBER) IS
v_cnt NUMBER;
BEGIN
SELECT COUNT(*) INTO v_cnt
FROM T_ITM_EVL_SUM
WHERE ITM_ID = p_itm; -- 요약 행이 있나
IF v_cnt = 0 THEN
INSERT INTO T_ITM_EVL_SUM (ITM_ID, EVL_CNT, EVL_PT_SUM, LAST_EVL_DT)
VALUES (p_itm, 1, p_pt, SYSDATE);
ELSE
UPDATE T_ITM_EVL_SUM
SET EVL_CNT = EVL_CNT + 1, EVL_PT_SUM = EVL_PT_SUM + p_pt, LAST_EVL_DT = SYSDATE
WHERE ITM_ID = p_itm;
END IF;
END;
[TKPROF 요약 — 지난 화요일 평가 10,000건 (학습용 예시)]
SQL Execute Rows query current
SELECT COUNT(*) FROM T_ITM_EVL_SUM WHERE ITM_ID = :B1 10,000 10,000 10,000 0
UPDATE T_ITM_EVL_SUM SET EVL_CNT = EVL_CNT + 1, … 9,989 9,989 9,989 10,312
INSERT INTO T_ITM_EVL_SUM (…) VALUES (…) 11 8 14 57
합계 SQL 실행 20,000 · 논리 읽기 약 40,400 · redo 약 3.1 MB
[오류 로그 — 10:00:07 ~ 10:01:52]
ORA-00001: unique constraint (SQLP.PK_T_ITM_EVL_SUM) violated 3건
신상품 3개에서, 같은 상품의 첫 평가가 두 세션에서 거의 동시에 들어왔다
평가 등록 화면 '등록 실패' 3건 (평가 INSERT까지 함께 롤백)
MERGE … USING DUAL을 SQL 실행 횟수, 읽는 양과 redo, 동시 등록에서의 안전성으로 비교하시오.