Post

데이터 정합성의 핵심, 트랜잭션 설계 기초

데이터 정합성의 핵심, 트랜잭션 설계 기초

트랜잭션 설계의 기초는 데이터 정합성과 일관성의 기본 개념을 익히는 것을 목표로 합니다. 이는 “비즈니스 데이터를 어떻게 저장·연결·보호·확장할지 결정하는 설계도”인 데이터베이스 설계의 중요한 부분입니다.

트랜잭션이란?

트랜잭션은 더 이상 나눌 수 없는 하나의 완결된 작업 단위를 의미합니다. 이는 모든 쿼리가 전부 성공적으로 반영되거나, 아니면 전부 무효화되어야 하는 특성을 가집니다. 일부만 성공하거나 실패하는 상황은 시스템의 신뢰성을 해치므로, 트랜잭션은 시스템 신뢰성의 핵심 기초가 되는 단위입니다.

트랜잭션의 4대 특성 (ACID)

트랜잭션은 네 가지 핵심 특성(ACID)을 가집니다.

  1. 원자성 (Atomicity)
    • 설명: 트랜잭션 내의 모든 작업이 전부 성공하거나, 전부 실패하여 원래 상태로 돌아가야 합니다 (All or Nothing).
    • 예시: A에서 B로 이체하는 과정에서 출금은 성공했지만 입금이 실패한 경우, 전체 작업은 롤백(ROLLBACK)되어야 합니다.
  2. 일관성 (Consistency)
    • 설명: 트랜잭션이 성공적으로 완료되면, 데이터베이스의 상태는 항상 일관되고 정합성을 유지해야 합니다.
    • 예시: A 계좌에서 빠져나간 금액만큼 B 계좌에 더해져야 두 계좌의 총액 합이 트랜잭션 이전과 동일하게 유지됩니다.
  3. 격리성 (Isolation)
    • 설명: 여러 트랜잭션이 동시에 수행되더라도, 각 트랜잭션은 마치 혼자 실행되는 것처럼 서로에게 영향을 주지 않아야 합니다. 다른 트랜잭션의 중간 상태를 읽을 수 없습니다.
    • 예시: 다른 트랜잭션이 진행 중인 동안, 해당 트랜잭션의 중간 변경사항이 다른 트랜잭션에 노출되지 않습니다.
  4. 지속성 (Durability)
    • 설명: 트랜잭션이 성공적으로 완료(COMMIT)되면, 그 결과는 시스템 오류(예: 서버 종료)가 발생하더라도 영구적으로 반영되어야 합니다.

실전 트랜잭션 단위 설계 예시: 상품 주문 흐름

상품 주문과 같은 비즈니스 흐름은 하나의 트랜잭션 단위로 설계되어야 합니다.

  1. 주문 정보 입력
  2. 재고 차감
  3. 포인트 차감
  4. 배송 정보 저장

이 모든 단계가 하나의 트랜잭션으로 묶여서, 모두 성공하면 COMMIT되고, 하나라도 실패하면 전체가 ROLLBACK되어야 합니다.

트랜잭션과 설계의 관계

트랜잭션 설계는 다음과 같은 DB 설계 요소들과 밀접하게 연관됩니다.

  • 테이블 간 제약조건 (FK 등): 참조 무결성을 트랜잭션 내에서 보장해야 합니다.
  • 락(Lock) 범위 조정: 격리 수준, 인덱스 설계와 연결되어 동시성 문제를 관리합니다.
  • Outbox 패턴: 트랜잭션과 메시지 발행 사이의 정합성 경계를 설정하는 데 사용됩니다. Outbox 패턴은 DB 쓰기와 동시에 메시지 큐에 이벤트를 발행할 때 발생할 수 있는 데이터 정합성 문제를 방지하기 위해, 이벤트 발행 요청을 DB 안에 먼저 적재한 후 별도 프로세스가 이를 읽어 큐에 전송하는 방식입니다.
  • 상태 전이: 하나의 트랜잭션 내에서 ‘주문’ → ‘결제 완료’ → ‘배송 중’과 같은 상태 변경이 완료되어야 합니다.

격리 수준과 동시성

DBMS마다 기본 격리 수준이 다르며, 격리 수준은 정합성과 동시성 성능 사이의 균형을 조절합니다. 격리 수준이 높을수록 정합성은 올라가지만, 동시성 성능은 낮아지므로 서비스 특성에 맞춰 선택해야 합니다.

  • READ COMMITTED: 다른 트랜잭션의 미커밋 데이터 읽기(Dirty Read)를 막지만, 같은 행을 두 번 읽을 때 값이 바뀔 수 있는 현상(Non-repeatable Read)은 허용합니다. 뉴스/게시판 목록처럼 읽기 위주 화면에 적합하며, Gap Lock이 적어 동시성이 높습니다.
  • REPEATABLE READ (MySQL 기본값): 트랜잭션이 첫 SELECT를 실행한 순간의 스냅샷을 끝까지 유지하며, Dirty Read는 물론 Non-repeatable Read도 방지합니다. MySQL은 Gap Lock까지 걸어 팬텀 현상(Phantom Read)도 대부분 막습니다. 장바구니 합계 계산이나 재고 차감처럼 “읽고 곧바로 쓰는” 패턴이 많은 로직에 적합합니다.
  • SERIALIZABLE: 모든 SELECT가 공유/범위 락을 잡아 실질적으로 순차 처리처럼 보장하며, 팬텀 현상까지 100% 차단합니다. 성능은 가장 느리지만, 회계, 결제 승인, 금융 이체 등 높은 정합성이 요구되는 업무에 적합합니다.
This post is licensed under CC BY 4.0 by the author.