데이터베이스 트랜잭션과 일관성 (Database Transactions and Consistency)

목차


트랜잭션이란

트랜잭션(Transaction) 은 데이터베이스에서 하나의 논리적 작업 단위를 안전하게 처리하기 위한 실행 범위입니다. 계좌 이체, 주문 생성, 재고 차감처럼 여러 단계가 모두 성공하거나 모두 실패해야 하는 작업을 묶는 데 사용합니다.

이 문서는 데이터베이스와 저장소 관점에서 일관성과 트랜잭션을 어떻게 보장할지를 설명합니다.
서비스 전체에서 어떤 일관성 모델을 선택할지, CAP과 분산 ID 같은 시스템 설계 판단은 분산 시스템 문서와 함께 보면 좋습니다.

예를 들어 계좌 이체는 다음 두 작업이 함께 보장돼야 합니다.

  1. A 계좌 잔액 차감
  2. B 계좌 잔액 증가

중간에 하나만 반영되면 데이터가 깨지므로, 이런 작업은 트랜잭션 경계 안에서 처리해야 합니다.


ACID

트랜잭션의 핵심 속성은 보통 ACID 로 설명합니다.

  • Atomicity: 모두 성공하거나 모두 실패해야 합니다.
  • Consistency: 트랜잭션 전후로 데이터 무결성 규칙이 유지돼야 합니다.
  • Isolation: 동시에 실행되는 트랜잭션이 서로의 중간 상태를 함부로 보지 않아야 합니다.
  • Durability: 커밋된 결과는 장애가 나도 유지돼야 합니다.

면접에서는 ACID를 외우는 것보다, 원자성은 rollback, 격리성은 락/MVCC, 지속성은 WAL/redo log 같은 복구 메커니즘과 연결해서 설명하는 편이 좋습니다.


격리 수준

격리 수준은 동시에 실행되는 트랜잭션 간 간섭을 어느 정도 허용할지 정하는 정책입니다. 관계형 데이터베이스는 보통 네 가지 수준을 제공합니다.12

격리 수준 Dirty Read Non-Repeatable Read Phantom Read 특징
Read Uncommitted 가능 가능 가능 거의 사용하지 않음
Read Committed 방지 가능 가능 많은 DB의 기본 후보
Repeatable Read 방지 방지 구현에 따라 다름 MySQL InnoDB 기본값
Serializable 방지 방지 방지 가장 안전하지만 비용 큼

격리 수준은 높을수록 안전하지만, 락 경합과 대기 시간이 늘어날 수 있습니다.
그래서 항상 최고 수준을 쓰는 것이 정답은 아닙니다.

읽기 이상 현상

  • Dirty Read: 다른 트랜잭션이 아직 커밋하지 않은 값을 읽는 현상
  • Non-Repeatable Read: 같은 행을 다시 읽었는데 값이 달라진 현상
  • Phantom Read: 같은 조건으로 다시 조회했는데 행 개수가 달라진 현상

면접에서는 “팬텀 리드는 새로운 행이 보이는 문제”까지 구분해 말하면 좋습니다.


락과 MVCC

트랜잭션 격리성은 주로 락(Lock)MVCC(Multi-Version Concurrency Control) 로 구현됩니다.

  • 락 기반 제어: 특정 row나 범위를 잠가 충돌을 막습니다.
  • MVCC: 같은 데이터의 여러 버전을 유지해 읽기와 쓰기 충돌을 줄입니다.

예를 들어 PostgreSQL은 MVCC를 강하게 활용하고, MySQL InnoDB도 MVCC와 락을 함께 사용합니다.12

실제 면접에서는 여기서 바로 SELECT ... FOR UPDATE, 낙관적 잠금, 데드락, UNIQUE 제약 기반 중복 방지 같은 꼬리질문으로 이어지는 경우가 많습니다. 이 구현 관점은 데이터베이스 동시성 제어와 락 (Concurrency Control and Locking) 문서에서 더 직접적으로 다룹니다.

중요한 포인트는 다음입니다.

  • 격리 수준은 DBMS마다 구현 방식이 조금씩 다릅니다.
  • 같은 Repeatable Read라도 DB마다 phantom 처리 방식이 다를 수 있습니다.
  • 성능 문제처럼 보이지만 실제 원인은 락 경합인 경우가 많습니다.

분산 트랜잭션

단일 데이터베이스 안에서는 트랜잭션이 비교적 단순하지만, 여러 서비스나 여러 저장소에 걸치면 난이도가 크게 올라갑니다.

대표 예시는 다음과 같습니다.

  • 주문 서비스는 주문을 생성
  • 결제 서비스는 결제를 승인
  • 재고 서비스는 수량을 차감

이 세 단계를 모두 하나의 글로벌 트랜잭션처럼 다루고 싶지만, 네트워크 장애와 서비스 장애 때문에 단일 DB처럼 처리하기 어렵습니다.

2단계 커밋

2단계 커밋(2PC) 은 참여자들이 먼저 커밋 가능 여부를 확인한 뒤, 모두 준비되면 실제 커밋하는 방식입니다.

  • 장점: 강한 원자성을 제공할 수 있습니다.
  • 단점: coordinator 장애 시 블로킹될 수 있고, 지연과 복잡도가 큽니다.

실무 마이크로서비스에서는 성능과 장애 전파 문제 때문에 2PC를 적극적으로 쓰지 않는 경우가 많습니다.

Saga 패턴

Saga 는 큰 트랜잭션을 여러 개의 로컬 트랜잭션으로 나누고, 중간 실패 시 보상 작업을 수행하는 방식입니다.

예를 들어:

  1. 주문 생성
  2. 결제 승인
  3. 재고 차감
  4. 배송 생성

3단계에서 실패하면, 2단계 결제를 취소하고 1단계 주문 상태를 실패로 되돌리는 식으로 보상합니다.

항목 2단계 커밋 Saga
일관성 강한 일관성 지향 최종적 일관성 지향
장점 원자성 설명이 직관적 확장성과 장애 대응에 유리
단점 블로킹과 성능 부담 보상 로직 설계가 복잡
적합한 경우 강한 일관성이 절대적인 내부 시스템 마이크로서비스, 비동기 워크플로

최종적 일관성

최종적 일관성(Eventual Consistency) 은 어떤 시점에는 데이터가 잠시 다를 수 있지만, 시간이 지나면 일관된 상태로 수렴하는 모델입니다.

이 모델은 다음 상황에서 자주 등장합니다.

  • 비동기 복제
  • 이벤트 기반 아키텍처
  • CQRS
  • 분산 캐시 갱신

핵심은 “일관성이 약하다”가 아니라 즉시 일관성을 포기하고 가용성과 확장성을 얻는 설계라는 점입니다.

이때 애플리케이션은 다음을 준비해야 합니다.

  • 재시도 가능성
  • 중복 이벤트 처리
  • idempotency 보장
  • 사용자에게 상태가 전파 중임을 드러내는 UX

면접 포인트

  • 트랜잭션은 ACID 속성만 외우는 문제가 아니라, 어떤 경계를 하나의 작업으로 볼지 정하는 문제입니다.
  • 격리 수준은 높을수록 안전하지만 성능 비용이 커질 수 있습니다.
  • Repeatable Read와 Serializable 차이를 이상 현상 기준으로 설명할 수 있어야 합니다.
  • 분산 환경에서는 2PC보다 Saga와 최종적 일관성을 선택하는 경우가 많습니다.
  • 실무에서는 락 경합, 타임아웃, 재시도, 중복 처리까지 함께 설명해야 답변이 강해집니다.

참고 자료