본문 바로가기

오류·예외·동시성의 첫 직관

파일이 없거나 결제가 거절될 수 있고, 두 사용자가 같은 마지막 재고를 동시에 주문할 수 있다. 정상 경로를 한 줄씩 차례대로 실행한다고만 가정하면 첫 번째 문제의 실패 경로를 놓치고, 두 번째 문제에서 실행 순서에 따라 결과가 바뀌는 이유를 설명하지 못한다.

정상 순서만 그린 프로그램은 현실에서 깨진다

파일이 없거나 결제가 거절될 수 있고, 두 사용자가 같은 마지막 재고를 동시에 주문할 수 있다. 정상 경로를 한 줄씩 차례대로 실행한다고만 가정하면 첫 번째 문제의 실패 경로를 놓치고, 두 번째 문제에서 실행 순서에 따라 결과가 바뀌는 이유를 설명하지 못한다.

예외는 정상 흐름에서 처리하기 어려운 실패를 전달하고, 동시성은 여러 작업의 진행을 겹치게 구성한다. 경쟁조건은 겹친 작업이 공유상태를 다룰 때 순서에 따라 잘못된 결과가 생기는 조건이다.

먼저 되짚기: 흐름과 상태를 함께 본다

제어흐름은 다음 실행 위치를, 상태는 같은 입력에도 다음 행동을 달라지게 하는 기억을 설명했다. 예외는 제어흐름을 실패 처리 위치로 바꾸고, 동시 작업은 같은 상태를 서로 다른 순서로 읽고 쓸 수 있다. 이번 절은 이미 배운 흐름과 상태에 실패와 겹침을 더한다.

실패 경로와 겹치는 실행을 기존 흐름에 더한다

제어흐름에는 정상 진행과 예외 전파 경로가 있다. 공유상태를 다루는 작업이 겹칠 때는 재고 변경의 실행 순서가 규칙을 깨뜨리는지 따로 확인한다. 예외와 경쟁조건은 서로 다른 축이다.

예외

예외(exception)는 정상 흐름으로 처리하기 어려운 실패나 비정상 상태를 전달하는 메커니즘이다. 예외가 발생하면 현재 연산의 정상 진행을 멈추고, 처리할 수 있는 가까운 호출자까지 실패 정보가 전달된다. 처리할 수 없는 예외는 더 위로 보내되 필요한 자원 정리는 보장해야 한다.

동시성

동시성(concurrency)은 여러 작업의 진행이 시간상 겹치도록 구조화하는 성질이다. 한 CPU가 작업을 짧게 번갈아 실행해도 진행 기간은 겹칠 수 있다. 여러 CPU가 같은 순간에 실제로 실행하는 병렬성과 관련되지만, 동시성은 우선 여러 진행의 상호작용을 다루는 구조에 초점을 둔다.

경쟁조건 전에 동시성을 다시 잇는다

동시성은 여러 작업의 진행 구간이 겹치도록 구조화하는 성질이다. 결과의 올바름이 이 겹침의 우연한 순서에 의존하면 경쟁조건이 된다.

동시 실행 자체가 버그는 아니다

두 작업이 겹쳐도 공유상태를 안전하게 다루면 올바를 수 있다. 가능한 interleaving 중 일부가 규칙을 깨는지를 확인한다.

경쟁조건

경쟁조건은 실행 순서에 따라 공유상태의 결과가 달라지는 결함 조건이다. 단순히 작업이 동시에 존재한다는 뜻이 아니다. 올바름이 우연한 실행 순서나 속도에 의존하고, 가능한 순서 중 일부가 규칙을 깨뜨릴 때 경쟁조건이 된다.

마지막 재고 하나가 두 번 팔리는 과정

재고가 1이고 주문 A와 B가 다음 세 단계를 각각 수행한다고 하자.

시간주문 A주문 B관찰
1재고 1을 읽음재고 1
2재고 1을 읽음두 작업이 같은 옛 값을 가짐
31 > 0이므로 승인승인 1건
41 > 0이므로 승인승인 2건
5재고 0을 기록재고 0
6재고 0을 기록승인 2건·재고 0: 업무 규칙 위반

각 주문을 홀로 실행하면 맞지만 읽기–판단–쓰기가 서로 끼어들어 두 번 승인된다. 이 세 단계를 하나의 배타적 변경으로 묶거나, 저장된 값이 여전히 읽었던 값일 때만 갱신하도록 검사해야 한다.

주문 처리 중 저장 실패가 발생하면 예외는 실패 정보를 상위 흐름으로 전달한다. 그러나 예외를 잡았다는 사실만으로 이미 수행한 결제나 재고 변경이 자동 취소되지는 않는다. 어떤 상태가 바뀌었는지 기록하고 되돌리기·재시도·담당자 확인 중 하나를 선택해야 한다.

ER-1: 재고 1개에 두 주문이 겹치는 순서를 적는다

초기 재고가 1이고 두 작업 A, B가 각각 “재고가 1 이상이면 1 감소 후 성공”을 수행한다고 하자.

순서AB재고
11 읽음1
21 읽음1
3성공 판단·0 기록0
4이미 읽은 1로 성공 판단·0 기록0

두 주문이 모두 성공했으므로 업무 규칙 “재고 1개는 한 주문에만 배정”을 위반한다. 단순히 마지막 숫자가 0이라는 이유로 정상이라고 판정하지 않는다.

이처럼 A와 B의 단계가 번갈아 끼어드는 실행 순서를 interleaving이라고 쓴다. 보호된 예약에서는 A가 읽기·판단·쓰기를 마칠 때까지 B가 같은 재고의 변경 구간에 들어가지 못하게 한다. A는 재고 1을 읽고 한 개를 예약해 0을 기록한 뒤 성공한다. 그다음 B는 새 재고 0을 읽어 부족으로 거절되며 결과는 성공 1건·거절 1건·재고 0이다. 이 구간을 하나로 보이게 보호하는 것을 여기서는 원자적 예약이라고 부르며, 중간의 검사와 차감을 서로 다른 작업이 끼어들 수 있는 두 연산으로 공개하지 않는다. 잠금은 이런 보호 구간에 한 작업만 들어가게 하는 방법이며 구체 구현은 뒤에서 배운다.

결제 예외도 상태를 따라 보자. 주문42가 재고를 예약한 뒤 결제 호출에서 통신 응답을 받지 못했다고 가정한다. 이때 결제가 안 되었다고 확정할 수도, 성공했다고 확정할 수도 없으므로 주문은 확인대기로 두고 결제사에 주문42의 기존 결과를 확인한다. 이미 승인되었다면 그 결과를 재사용해 확정하고, 명확하게 거절되었다면 예약을 해제해 재고를 되돌린다. 같은 주문42의 요청을 반복해도 새 청구를 만들지 않는 계약을 결제 경계에 둔다. 결과가 불명확한 동안 즉시 재청구하거나 재고를 풀어 다른 주문에 팔아 버리는 대안은 중복 청구·재고 약속 위반 때문에 제외한다.

예외 처리 경계는 원인·주문번호·현재 상태를 기록하고, 파일이나 보호 구간을 사용 중이었다면 실패 여부와 관계없이 닫거나 해제한다. 예약이라는 업무 상태를 되돌리는 판단과 잠금 같은 실행 자원을 해제하는 동작은 다르다. 예외를 잡았다는 사실만으로 둘 다 끝났다고 생각하지 않는다.

반면 외부 결제 호출이 실패해 예외가 발생하는 문제는 경쟁조건과 다른 축이다. 예외 처리와 동시성 제어를 한 기법으로 뭉개지 않는다.

무엇을 어떻게 처리할 것인가

상황적절한 표현·통제피해야 할 반응
예상 가능한 업무 거절결괏값과 이유로 정상 분기모든 거절을 시스템 예외로 처리
계속할 수 없는 기술 실패예외로 전파하고 경계에서 복구·변환실패를 삼키고 성공처럼 진행
독립 작업의 대기 겹침동시 실행으로 대기시간 활용공유상태 통제 없이 무작정 병렬화
공유상태 변경한 번에 처리되는 구간·버전 검사·메시지 전달실행 속도가 충분히 다를 것이라 가정

동시성을 늘리면 자원을 기다리는 동안 다른 일을 진행해 처리량을 높일 수 있지만, 순서·공유상태·취소·실패 조합이 복잡해진다. 먼저 소유권을 분리해 공유를 줄이고, 정말 공유해야 하는 상태에만 동기화 범위를 둔다.

실패조건과 방어

예외 삼키기는 실패를 기록하거나 복구하지 않고 빈 결과로 바꾸는 처리다. 처리할 수 있는 경계에서만 잡고 원인과 문맥을 보존한다.

지나치게 넓은 예외 처리는 서로 다른 원인을 모두 같은 실패로 취급한다. 복구 행동이 같은 실패만 함께 처리한다.

검사 후 실행 분리는 “재고가 있다”를 확인한 뒤 실제 차감까지 다른 작업이 끼어들 수 있게 한다. 판단과 변경을 하나의 보호된 연산으로 묶는다.

큰 잠금 범위는 경쟁을 막지만 독립 작업까지 기다리게 하고 서로 상대가 가진 자원을 기다리는 교착을 만들 수 있다. 보호할 불변조건에 필요한 최소 범위를 정하고 자원 획득 순서를 통일한다.

한 번의 재현만으로 안전하다고 판정하면 특정 실행 순서만 시험한 결과를 일반화하게 된다. 반복·부하·강제 지연으로 여러 순서를 만들고 결과의 불변조건을 검증한다.

자체 10점 문제

예외·동시성·경쟁조건의 차이와 통제 원칙을 설명하시오.

요구어는 설명이다. 실패 전파와 겹치는 실행, 순서 의존 결함을 구분한다.

10점 풀이 방향과 모범답안 보기

10점 답안 목차

  1. 예외와 실패전파
  2. 동시성
  3. 경쟁조건
  4. 공유상태 interleaving
  5. 자원정리·동기화 경계

10점 답안 도식

개념판별 조건통제
예외정상 진행을 계속할 수 없는 실패실패 전파·경계 복구·자원 정리
동시성여러 작업의 진행 구간이 겹침소유권·취소·상호작용 설계
경쟁조건겹친 작업의 우연한 순서가 규칙을 위반공유를 줄이고 판단·변경을 보호

모범답안 축약본: 실패 경로와 실행 순서를 설계한다

문제: 예외·동시성·경쟁조건의 차이와 통제 원칙을 설명하시오. 예외는 정상 반환만으로 처리하기 어려운 실패를 호출자에게 전달하는 제어 경로지만, 이미 변경한 상태를 자동 복구하지 않는다. 동시성은 둘 이상의 작업 진행구간이 겹치는 성질이며 한 실행 장치의 번갈아 실행도 포함한다. 경쟁조건은 실행 순서에 따라 결과의 올바름이 달라지는 결함이다. ER-1에서는 두 주문이 각각 재고 1을 읽고 0을 덮어써 최종 재고가 0인데도 두 건을 승인한다. 공유 변경을 줄이고 재고 확인과 차감을 하나의 보호된 원자적 예약으로 묶으며, 자원 획득 순서를 통일한다. 예외 시 현재 업무 상태를 확인해 보상·기존 결과 확인·재시도 경로를 선택하고 실행 자원을 반드시 해제한다. 다양한 실행 순서에서 재고 비음수뿐 아니라 한 개당 성공 한 건이라는 불변조건도 검증한다.

자체 25점 문제

재고 1개 동시 주문과 결제 예외를 함께 처리하는 주문 흐름을 설계하시오.

요구어는 설계다. 공유상태 원자성, 예외 전파·정리, 재시도·중복의 경계를 제시한다.

25점 풀이 방향과 모범답안 보기

25점 답안 목차

  1. 공유 재고 규칙
  2. read-check-update 원자성
  3. 충돌/실패 반환
  4. 결제 예외 경로
  5. 자원정리
  6. 같은 주문의 반복 요청과 중복 처리 방지
  7. interleaving 테스트
  8. 모니터링·오류 분류

25점 답안 도식

결제 결과가 불명확하면 기존 결과를 확인한다 · 상태 따라가기

주문 42의 재고 읽기·판단·차감을 보호하며 아직 결제를 요청하지 않는다. 모든 단계에서 주문 42·재고·결제·확인의 위치를 유지하며 값과 허용 조건을 함께 확인합니다.

결제 결과가 불명확하면 기존 결과를 확인한다

상자 안의 대상과 화살표의 조건을 함께 읽으세요. 좁은 화면에서는 같은 관계를 세로로 재배치한 도식을 보여 줍니다.

결제 결과가 불명확하면 기존 결과를 확인한다재고 원자 예약이 실패하면 거절한다. 예약 성공 후 주문42의 결제를 요청하며 승인이 확인되면 같은 결과로 주문을 확정하고, 명확히 거절되면 예약을 해제한다. 응답 미확인은 확인대기로 남겨 주문42의 기존 결과를 조회한다. 이 조회가 새 청구를 만드는 재요청이 되어서는 안 되며, 실행 자원 해제는 업무 예약 해제와 별개다.reserve → acceptedaccepted → pay: 성공accepted → reject: 실패pay → resultresult → confirm: 승인 확인result → release: 명확한 거절result → wait: 응답 미확인wait → result: 기존 조회성공실패승인 확인명확한 거절응답 미확인기존 조회재고 원자 예약: 읽기·판단·차감 보호재고 원자 예약읽기·판단·차감 보호예약 성공?예약 성공?재고 부족 거절재고 부족 거절주문42 결제: 기존 결과 재사용 계약주문42 결제기존 결과 재사용 계약결제 결과?결제 결과?주문 확정: 같은 승인 결과주문 확정같은 승인 결과예약 해제: 명확한 거절일 때예약 해제명확한 거절일 때확인대기: 기존 결과 조회확인대기기존 결과 조회
결제 결과가 불명확하면 기존 결과를 확인한다재고 원자 예약이 실패하면 거절한다. 예약 성공 후 주문42의 결제를 요청하며 승인이 확인되면 같은 결과로 주문을 확정하고, 명확히 거절되면 예약을 해제한다. 응답 미확인은 확인대기로 남겨 주문42의 기존 결과를 조회한다. 이 조회가 새 청구를 만드는 재요청이 되어서는 안 되며, 실행 자원 해제는 업무 예약 해제와 별개다.reserve → acceptedaccepted → pay: 성공accepted → reject: 실패pay → resultresult → confirm: 승인 확인result → release: 명확한 거절result → wait: 응답 미확인wait → result: 기존 조회성공실패승인 확인명확한 거절응답 미확인기존 조회재고 원자 예약: 읽기·판단·차감 보호재고 원자예약읽기·판단·차감보호예약 성공?예약성공?재고 부족 거절재고 부족거절주문42 결제: 기존 결과 재사용 계약주문42 결제기존 결과 재사용계약결제 결과?결제결과?주문 확정: 같은 승인 결과주문 확정같은 승인 결과예약 해제: 명확한 거절일 때예약 해제명확한 거절일 때확인대기: 기존 결과 조회확인대기기존 결과 조회

재고 원자 예약이 실패하면 거절한다. 예약 성공 후 주문42의 결제를 요청하며 승인이 확인되면 같은 결과로 주문을 확정하고, 명확히 거절되면 예약을 해제한다. 응답 미확인은 확인대기로 남겨 주문42의 기존 결과를 조회한다. 이 조회가 새 청구를 만드는 재요청이 되어서는 안 되며, 실행 자원 해제는 업무 예약 해제와 별개다.

이 예의 조건

  • 재고 원자 예약이 실패하면 거절한다. 예약 성공 후 주문 42의 결제를 요청하며 승인이 확인되면 같은 결과로 주문을 확정하고, 명확히 거절되면 예약을 해제한다. 응답 미확인은 확인대기로 남겨 주문 42의 기존 결과를 조회한다. 이 조회가 새 청구를 만드는 재요청이 되어서는 안 되며, 실행 자원 해제는 업무 예약 해제와 별개다.
  • 이 원문의 교육용 사례·조건 안에서 상태를 대조합니다. 실제 구축·실험 결과나 원문에 없는 성능 보장을 추가하지 않습니다.
관계도의 보충 설명
원그림의 모든 대상과 설명
대상원 설명
재고 원자 예약읽기·판단·차감 보호
예약 성공?원그림의 대상
재고 부족 거절원그림의 대상
주문 42 결제기존 결과 재사용 계약
결제 결과?원그림의 대상
주문 확정같은 승인 결과
예약 해제명확한 거절일 때
확인대기기존 결과 조회
원그림의 모든 관계와 조건
연결원 라벨·방향
재고 원자 예약 → 예약 성공?라벨 없는 연결 / 정방향 / 실선
예약 성공? → 주문 42 결제성공 / 정방향 / 실선
예약 성공? → 재고 부족 거절실패 / 정방향 / 실선
주문 42 결제 → 결제 결과?라벨 없는 연결 / 정방향 / 실선
결제 결과? → 주문 확정승인 확인 / 정방향 / 실선
결제 결과? → 예약 해제명확한 거절 / 정방향 / 실선
결제 결과? → 확인대기응답 미확인 / 정방향 / 실선
확인대기 → 결제 결과?기존 조회 / 정방향 / 점선
예의 값과 변화
관찰·상황값·보충 정보변화·이유
원자 예약 성공 전

주문 42의 재고 읽기·판단·차감을 보호하며 아직 결제를 요청하지 않는다.

  • 주문 42·재고: 재고 원자 예약 중
  • 결제·확인: 결제 요청 전
  • 예약 실패는 재고 부족 거절로 끝나므로 결제를 요청할 수 없다.
예약 성공 뒤 결제 요청

예약 성공을 확인한 뒤 주문 42의 결제를 요청하고 결과를 기다린다.

  • 주문 42·재고: 예약 성공·유지
  • 결제·확인: 주문 42 결제 결과 대기
  • 예약 성공과 결제 요청 사이의 경계를 지키며 아직 주문을 확정하지 않는다.
대안 1: 승인 확인

공통 시작점인 예약 성공·결제 결과 대기에서 승인 확인이 나온 경우다.

  • 주문 42·재고: 같은 승인으로 주문 확정
  • 결제·확인: 승인 확인
  • 이 장면의 확정은 다음 거절·미확인 장면과 배타적인 대안이다.
대안 2: 명확한 거절

예약 성공·결제 결과 대기로 재설정하고 명확한 거절이 나온 경우를 본다.

  • 주문 42·재고: 예약 해제
  • 결제·확인: 명확한 거절
  • 확정된 주문의 후속이 아니며 해제 동작의 실패·재확인은 별도로 남는다.
대안 3: 응답 미확인

예약 성공·결제 결과 대기로 재설정하고 응답을 확인하지 못한 경우를 본다.

  • 주문 42·재고: 확인대기·해제 보류
  • 결제·확인: 주문 42 기존 결과 조회
  • 승인됐을 수 있으므로 새 청구나 즉시 해제를 하지 않고 같은 결과를 확인한다.

결제 결과가 불명확하면 기존 결과를 확인한다 · 상태 따라가기

주문 42의 재고 읽기·판단·차감을 보호하며 아직 결제를 요청하지 않는다. 모든 단계에서 주문 42·재고·결제·확인의 위치를 유지하며 값과 허용 조건을 함께 확인합니다.

결제 결과가 불명확하면 기존 결과를 확인한다

상자 안의 대상과 화살표의 조건을 함께 읽으세요. 좁은 화면에서는 같은 관계를 세로로 재배치한 도식을 보여 줍니다.

결제 결과가 불명확하면 기존 결과를 확인한다재고 원자 예약이 실패하면 거절한다. 예약 성공 후 주문42의 결제를 요청하며 승인이 확인되면 같은 결과로 주문을 확정하고, 명확히 거절되면 예약을 해제한다. 응답 미확인은 확인대기로 남겨 주문42의 기존 결과를 조회한다. 이 조회가 새 청구를 만드는 재요청이 되어서는 안 되며, 실행 자원 해제는 업무 예약 해제와 별개다.reserve → acceptedaccepted → pay: 성공accepted → reject: 실패pay → resultresult → confirm: 승인 확인result → release: 명확한 거절result → wait: 응답 미확인wait → result: 기존 조회성공실패승인 확인명확한 거절응답 미확인기존 조회재고 원자 예약: 읽기·판단·차감 보호재고 원자 예약읽기·판단·차감 보호예약 성공?예약 성공?재고 부족 거절재고 부족 거절주문42 결제: 기존 결과 재사용 계약주문42 결제기존 결과 재사용 계약결제 결과?결제 결과?주문 확정: 같은 승인 결과주문 확정같은 승인 결과예약 해제: 명확한 거절일 때예약 해제명확한 거절일 때확인대기: 기존 결과 조회확인대기기존 결과 조회
결제 결과가 불명확하면 기존 결과를 확인한다재고 원자 예약이 실패하면 거절한다. 예약 성공 후 주문42의 결제를 요청하며 승인이 확인되면 같은 결과로 주문을 확정하고, 명확히 거절되면 예약을 해제한다. 응답 미확인은 확인대기로 남겨 주문42의 기존 결과를 조회한다. 이 조회가 새 청구를 만드는 재요청이 되어서는 안 되며, 실행 자원 해제는 업무 예약 해제와 별개다.reserve → acceptedaccepted → pay: 성공accepted → reject: 실패pay → resultresult → confirm: 승인 확인result → release: 명확한 거절result → wait: 응답 미확인wait → result: 기존 조회성공실패승인 확인명확한 거절응답 미확인기존 조회재고 원자 예약: 읽기·판단·차감 보호재고 원자예약읽기·판단·차감보호예약 성공?예약성공?재고 부족 거절재고 부족거절주문42 결제: 기존 결과 재사용 계약주문42 결제기존 결과 재사용계약결제 결과?결제결과?주문 확정: 같은 승인 결과주문 확정같은 승인 결과예약 해제: 명확한 거절일 때예약 해제명확한 거절일 때확인대기: 기존 결과 조회확인대기기존 결과 조회

재고 원자 예약이 실패하면 거절한다. 예약 성공 후 주문42의 결제를 요청하며 승인이 확인되면 같은 결과로 주문을 확정하고, 명확히 거절되면 예약을 해제한다. 응답 미확인은 확인대기로 남겨 주문42의 기존 결과를 조회한다. 이 조회가 새 청구를 만드는 재요청이 되어서는 안 되며, 실행 자원 해제는 업무 예약 해제와 별개다.

이 예의 조건

  • 재고 원자 예약이 실패하면 거절한다. 예약 성공 후 주문 42의 결제를 요청하며 승인이 확인되면 같은 결과로 주문을 확정하고, 명확히 거절되면 예약을 해제한다. 응답 미확인은 확인대기로 남겨 주문 42의 기존 결과를 조회한다. 이 조회가 새 청구를 만드는 재요청이 되어서는 안 되며, 실행 자원 해제는 업무 예약 해제와 별개다.
  • 이 원문의 교육용 사례·조건 안에서 상태를 대조합니다. 실제 구축·실험 결과나 원문에 없는 성능 보장을 추가하지 않습니다.

관계도의 보충 설명

원그림의 모든 대상과 설명
대상원 설명
재고 원자 예약읽기·판단·차감 보호
예약 성공?원그림의 대상
재고 부족 거절원그림의 대상
주문 42 결제기존 결과 재사용 계약
결제 결과?원그림의 대상
주문 확정같은 승인 결과
예약 해제명확한 거절일 때
확인대기기존 결과 조회
원그림의 모든 관계와 조건
연결원 라벨·방향
재고 원자 예약 → 예약 성공?라벨 없는 연결 / 정방향 / 실선
예약 성공? → 주문 42 결제성공 / 정방향 / 실선
예약 성공? → 재고 부족 거절실패 / 정방향 / 실선
주문 42 결제 → 결제 결과?라벨 없는 연결 / 정방향 / 실선
결제 결과? → 주문 확정승인 확인 / 정방향 / 실선
결제 결과? → 예약 해제명확한 거절 / 정방향 / 실선
결제 결과? → 확인대기응답 미확인 / 정방향 / 실선
확인대기 → 결제 결과?기존 조회 / 정방향 / 점선
예의 값과 변화
관찰·상황값·보충 정보변화·이유
원자 예약 성공 전

주문 42의 재고 읽기·판단·차감을 보호하며 아직 결제를 요청하지 않는다.

  • 주문 42·재고: 재고 원자 예약 중
  • 결제·확인: 결제 요청 전
  • 예약 실패는 재고 부족 거절로 끝나므로 결제를 요청할 수 없다.
예약 성공 뒤 결제 요청

예약 성공을 확인한 뒤 주문 42의 결제를 요청하고 결과를 기다린다.

  • 주문 42·재고: 예약 성공·유지
  • 결제·확인: 주문 42 결제 결과 대기
  • 예약 성공과 결제 요청 사이의 경계를 지키며 아직 주문을 확정하지 않는다.
대안 1: 승인 확인

공통 시작점인 예약 성공·결제 결과 대기에서 승인 확인이 나온 경우다.

  • 주문 42·재고: 같은 승인으로 주문 확정
  • 결제·확인: 승인 확인
  • 이 장면의 확정은 다음 거절·미확인 장면과 배타적인 대안이다.
대안 2: 명확한 거절

예약 성공·결제 결과 대기로 재설정하고 명확한 거절이 나온 경우를 본다.

  • 주문 42·재고: 예약 해제
  • 결제·확인: 명확한 거절
  • 확정된 주문의 후속이 아니며 해제 동작의 실패·재확인은 별도로 남는다.
대안 3: 응답 미확인

예약 성공·결제 결과 대기로 재설정하고 응답을 확인하지 못한 경우를 본다.

  • 주문 42·재고: 확인대기·해제 보류
  • 결제·확인: 주문 42 기존 결과 조회
  • 승인됐을 수 있으므로 새 청구나 즉시 해제를 하지 않고 같은 결과를 확인한다.

25점 모범답안

재고 확인과 감소를 서로 분리된 읽기·쓰기로 두지 않고 한 논리적 예약 연산으로 묶어 한 주문만 성공하도록 한다. ER-1의 두 작업 interleaving을 재현해 둘 다 성공하는 경로가 사라지는지 확인한다.

재고 예약 뒤 결제 호출에서 예외가 발생하면 예외를 숨겨 성공으로 처리하지 않고 주문 상태와 예약 해제/보상 정책을 실행한다. 재시도는 같은 주문이 두 번 청구되지 않도록 요청 식별자와 기존 결과 재사용 경계를 둔다.

동시성 제어는 순서 의존 공유상태에, 예외 처리는 실패 전파와 정리에 각각 적용한다. 두 문제를 구분해 로그·테스트도 interleaving 실패와 외부호출 실패를 별도로 보존한다.

구체적으로 초기 재고 1에서 A의 예약이 완료된 뒤 B가 새 재고 0을 읽게 보호해 성공 1건·거절 1건을 얻는다. A의 주문42에서 결제 응답이 불명확하면 확인대기로 유지하고 기존 승인 결과를 확인한다. 승인이 확인되면 같은 결과로 주문을 확정하며 명확한 거절 때만 예약을 해제한다. 실행 자원은 실패 때도 해제하고 주문번호·실패 원인·예약과 결제 상태를 담당자가 확인할 수 있게 남긴다. 무조건 재청구나 불명확한 결제 상태의 즉시 재고 해제는 제외한다. 시험은 A/B 순서를 바꾼 예약과 승인·거절·응답없음 후 같은 주문 재요청을 각각 대조한다.

출처와 적용 경계

본문은 안정된 예외·동시성 기초와 자체 재고 interleaving 예를 사용한다. 실제 lock·transaction·actor·async 예외 의미는 언어·런타임·저장소 제품의 계약을 확인한다.

30초 정리

  1. 예외는 정상 흐름으로 처리하기 어려운 실패를 전달하지만 이미 바뀐 상태를 자동으로 되돌리지는 않는다.
  2. 동시성은 여러 작업의 진행을 겹치게 하며, 병렬 실행 여부와 별개로 상호작용을 설계해야 한다.
  3. 경쟁조건은 올바름이 실행 순서에 의존하는 결함이므로 공유를 줄이고 판단과 변경을 안전한 한 단위로 묶는다.

자기교정과 조건 변경

잘못 쓴 답수정복습
동시 작업이 있으면 항상 race다순서에 따라 규칙이 깨지는지 본다동시성
최종 재고가 0이면 두 주문 성공도 정상이다성공 건수와 업무 불변조건을 함께 본다ER-1
예외처리만 잘하면 race도 해결된다실패전파와 공유상태 동기화를 분리한다비교
lock을 쓰면 모든 오류가 사라진다교착·범위·외부호출 등 다른 실패가 남는다실패
재시도는 실패한 호출을 그냥 다시 하면 된다같은 주문의 기존 결과와 중복 부작용을 확인한다ER-1

재고가 2개라면? 두 주문 성공이 허용될 수 있지만 세 주문 interleaving까지 같은 불변조건으로 검사한다.

결제가 예약 전에 먼저 실행되면? 재고 실패 시 결제 취소/환불 문제가 생기므로 순서와 보상 경계를 다시 설계한다.

공유상태가 없다면? 동시성 자체는 남아도 이 재고 race의 원인은 사라질 수 있다.