205. 오손 읽기 (Dirty Read) - 병행 수행 문제 커밋되지 않은 데이터 미확정 데이터 트랜잭션 격리성 위배 롤백 연쇄 취소

핵심 인사이트: (202번 3번 문제 심화) 내 통장 잔고가 0원이다. 엄마가 내 통장으로 100만 원을 입금하는 중이다(T1 시작). 100만 원이 찍혔는데 아직 은행 전산에 확정(COMMIT) 도장은 안 찍힌 '가짜 임시 상태'다. 나는 잔고 조회를 눌렀다. "오싸! 100만 원 있다!" 나는 신나서 100만 원짜리 명품 가방을 질렀다(T2 실행). 그런데 찰나의 순간! 엄마 폰이 배터리가 나가서 입금하던 게 에러가 나 취소(ROLLBACK)되어 내 잔고는 다시 0원이 됐다! 헉! 나는 세상에 존재하지도 않는 허공의 100만 원을 주워 먹고 가방을 사버린 꼴이다. "야! 엄마가 아직 완벽하게 입금 확정(COMMIT) 도장도 안 찍었는데, 왜 그 덜 익은 더러운 쓰레기 데이터(Dirty Data)를 내게 보여줘서 헛돈을 쓰게 만들어!!" 세상에 없는 가짜 찌꺼기를 주워 먹는 최악의 불량 식사, 오손 읽기다.

Ⅰ. 트랜잭션 임시 상태의 위험성

  • 198번에서 배웠듯, 트랜잭션이 데이터를 UPDATE 했더라도 **COMMIT 명령어를 치기 전까지는 그 데이터는 언제든 ROLLBACK 될 수 있는 불안정한 찌꺼기 상태(Uncommitted Data)**입니다.
  • 이 찌꺼기 데이터는 오직 그 데이터를 바꾼 본인(T1)의 밀실 안에서만 보여야 하고, 외부의 타인(T2)에게는 절대 노출되어서는 안 되는(격리성) 1급 비밀입니다.

Ⅱ. 오손 읽기 (Dirty Read)의 정확한 정의 🌟

  • 개념: 어떤 트랜잭션(T2)이 다른 트랜잭션(T1)이 수정했지만 '아직 COMMIT(확정) 하지 않은 미확정 상태의 더러운 데이터(Dirty Data)'를 훔쳐서 읽어가는(Read) 병행 수행 에러 현상입니다.
  • 이 현상 자체가 무조건 100% 버그를 일으키는 건 아닙니다. 문제는 T1이 변덕을 부릴 때 터집니다.

Ⅲ. 오손 읽기가 부르는 연쇄 대재앙 (작동 시나리오) 🌟 핵심 🌟

주워 먹은 가짜 데이터가 뱃속에서 폭발하는 과정입니다.

  1. 미확정 데이터 생성: 회사 관리자(T1)가 전 직원의 월급을 300만 원에서 500만 원으로 올리는 UPDATE를 쳤습니다. (아직 최종 결재 COMMIT 전입니다.)
  2. 더티 리드 (Dirty Read): 직원 철수(T2)가 자기 잔고 조회를 누릅니다. 격리성이 박살 나서 철수 눈에 **"500만 원"**이라는 덜 익은 쓰레기(Dirty) 데이터가 그대로 보입니다! 철수는 신나서 500만 원짜리 페라리 계약금으로 씁니다(T2 COMMIT).
  3. 태초마을 롤백 (재앙의 트리거): 그 순간, 관리자(T1)가 "아차차 실수! 사장님이 월급 동결이래!" 하며 500만 원 올린 것을 ROLLBACK(취소) 시켜버리고 300만 원으로 쓱 되돌립니다.
  4. 결과 (가짜를 먹은 놈의 멘붕): 철수(T2)가 주워 먹은 "500만 원"은 지구상 어디에도 존재한 적 없는 허깨비 유령 숫자가 되었습니다. 철수는 자기 통장 잔액보다 더 큰 돈을 써버린 미친 논리 모순(DB 붕괴)의 늪에 빠집니다.

Ⅳ. 이 찌꺼기를 막는 흑마법 (방어 수준) 🌟 기출 단골 🌟

DB는 뚜껑도 안 닫힌 쓰레기통을 어떻게 덮을까요?

Read Committed (커밋된 것만 읽어라!) 격리 수준

  • 전 세계 99%의 상용 DB(오라클 등)가 기본으로 세팅해 두는 절대 방패입니다.
  • 방어 로직: 철수(T2)가 데이터를 읽으러 왔는데, 관리자(T1)가 아직 500만 원으로 고치고 COMMIT 도장을 안 찍었습니다.
  • 철수한테 500만 원을 안 보여줍니다! 철수에게는 관리자가 고치기 전의 과거 확정 데이터인 '300만 원(Undo Log 스냅샷)'만 무조건 보여줍니다.
  • 500만 원은 관리자가 최종 COMMIT 도장을 쾅 찍은 1초 뒤부터만 철수 눈에 보이게 짠! 하고 나타납니다.
  • 이 간단한 규칙 하나로 오손 읽기(Dirty Read) 현상을 우주에서 완벽하게 소멸시켜 줍니다.

Ⅴ. 204번 모순성(Unrepeatable Read)과의 확실한 차이점 🌟

두 개를 헷갈리면 시험에서 무조건 틀립니다.

  • 오손 읽기 (Dirty Read): 남이 덜 고치고 아직 도장(COMMIT) 안 찍은 **'가짜 쓰레기 데이터'**를 읽었다가, 그게 취소(ROLLBACK)되어서 내가 주워 먹은 게 똥이 된 사고.
  • 모순성 (Unrepeatable Read): 남이 완벽하게 도장(COMMIT)까지 찍고 나간 **'진짜 확정 데이터'**를 읽었는데, 내가 두 번 읽는 사이에 값이 바뀌어 있어서 내 멘탈(일관성)이 흔들린 사고.

📢 섹션 요약 비유: **오손 읽기(Dirty Read)**는 제빵사가 빵을 오븐에 굽고 있는 중간에 손님이 '반죽 상태의 덜 익은 밀가루(미확정 Dirty Data)'를 몰래 훔쳐서 처먹고 배탈이 나는 대참사입니다. 제빵사(트랜잭션 T1)가 오븐에 반죽을 넣고 아직 다 구워졌다고 '땡!(COMMIT)' 종을 안 쳤습니다. 제빵사는 중간에 "아 이 빵 탔네, 버려야지(ROLLBACK)" 하고 쓰레기통에 넣으려 했습니다. 근데 굶주린 손님(트랜잭션 T2)이 주방 문을 몰래 열고 들어와, 아직 종도 안 친 그 반쯤 탄 빵 반죽을 진짜 완성된 빵인 줄 알고 허겁지겁 씹어 삼키고 소화(T2 COMMIT)시켜버린 겁니다. 제빵사는 빵을 쓰레기통에 버려버려 빵은 세상에서 없어졌는데, 손님 배 속에는 그 유령 빵의 포만감이 남아있는 완벽한 논리적 모순이 터집니다. 이 끔찍한 배탈을 막기 위해 오븐에 튼튼한 유리문(Read Committed 격리 수준)을 달아, 요리사가 "완성!(COMMIT)" 종을 칠 때까지는 손님이 오븐 안의 덜 익은 반죽(미확정 데이터)에 절대 손을 댈 수 없게 철저히 막아내는 것이 DB 격리성의 첫 번째 기본 방패입니다.