데이터베이스 따라잡기

트랜잭션과 ACID

meellon 2026. 6. 26. 05:30

학습 목표

트랜잭션이 논리적 작업 단위임을 설명할 수 있다.

ACID(원자성·일관성·격리·지속성) 각각이 보장하는 것을 구분할 수 있다.

COMMIT·ROLLBACK·SAVEPOINT의 역할을 설명할 수 있다.

암시적·명시적 트랜잭션과 autocommit 동작을 설명할 수 있다.

문제 상황

  • 이체 API가 출금만 성공하고 입금 전에 프로세스가 죽었다
    • 잔액만 줄고 상대 계좌는 그대로 — 반쪽 상태
  • UPDATE 두 번 중 하나만 반영된 채 클라이언트에 200 OK
    • 요청 단위 원자성 없음
  • 다른 세션에서 중간 값을 읽었다
    • 커밋 전 데이터가 보이면 Dirty Read
  • COMMIT 직후 전원 장애인데 재기동 후에도 반영됨
    • 지속성 — 디스크·로그 메커니즘 (WAL은 이후 편)
  • Spring @Transactional 없이 service 메서드 두 개를 각각 호출
    • 하나의 트랜잭션이 아님 — 경계 설계 필요

앞서 실행 계획으로 단일 쿼리 성능을 봤다. 트랜잭션은 여러 연산을 하나의 단위로 묶는 계약이다.

1. 트랜잭션이란

트랜잭션(Transaction) — DB 상태를 한 논리 단위로 바꾸는 연산 묶음.

  • All-or-nothing — 전부 반영되거나 전부 취소
  • BEGINCOMMIT / ROLLBACK 사이가 경계
  • 단일 SELECT도 트랜잭션 컨텍스트 안에서 실행 (읽기 일관성)
개념 의미
트랜잭션 애플리케이션·DB가 정한 작업 단위
커밋 변경을 영구 반영
롤백 트랜잭션 시작 이후 변경 폐기
세션 클라이언트 연결 — 트랜잭션은 세션당 하나 active (일반적)

2. ACID

관계형 DBMS가 트랜잭션에 대해 약속하는 네 가지 성질.

  영문 보장
A Atomicity (원자성) 트랜잭션 전부 또는 전무
C Consistency (일관성) 제약·불변식 유지 — 합법적 상태
I Isolation (격리) 동시 트랜잭션이 서로 간섭 최소화
D Durability (지속성) COMMIT 후 장애에도 유지

Atomicity (원자성)

  • 중간 실패 시 undo — 부분 반영 없음
  • DBMS 로그·롤백으로 구현 (undo log, MVCC rollback)

Consistency (일관성)

  • 애플리케이션 + DB 제약 공동 책임
    • PK, FK, CHECK, NOT NULL
    • balance >= 0 같은 비즈니스 규칙은 앱·트리거·CHECK
  • 트랜잭션 전후 DB가 무결한 상태 — A·I·D가 돕는 목표

Isolation (격리)

  • 동시 실행이 순차 실행동등한 결과에 가깝게
  • 격리 수준으로 트레이드오프 — Lost Update·Phantom 등은 다음 편

Durability (지속성)

  • COMMIT = 디스크에 기록됐다고 볼 수 있는 시점 (버퍼 flush·WAL)
  • Write-Ahead Log·checkpoint — 로깅·복구 편에서 상세

3. 원자성 예: 계좌 이체

UPDATE하나의 트랜잭션으로 묶는다.

BEGIN;

UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;

COMMIT;
시점 A 계좌 B 계좌 외부에서 보는 값
BEGIN 전 1000 500 1000 / 500
첫 UPDATE 후 (미커밋) 900 500 격리 수준에 따라 다름
COMMIT 후 900 600 900 / 600
ROLLBACK 시 1000 500 변경 없음
  • 두 번째 UPDATE가 FK 위반·제약 실패 → 전체 ROLLBACK
  • 애플리케이션에서 출금·입금을 별도 HTTP로 나누면 DB 트랜잭션 경계 밖

전체 예시는 code/transaction-examples.sql 참고.

4. COMMIT과 ROLLBACK

BEGIN;
  INSERT INTO orders (user_id, total) VALUES (42, 99.00);
  UPDATE inventory SET qty = qty - 1 WHERE sku = 'ABC';
  -- constraint violation here
ROLLBACK;   -- both statements undone

BEGIN;
  INSERT INTO orders (user_id, total) VALUES (42, 99.00);
  UPDATE inventory SET qty = qty - 1 WHERE sku = 'ABC';
COMMIT;     -- durable after commit (WAL flush policy)
명령 효과
BEGIN / START TRANSACTION 새 트랜잭션 시작
COMMIT 변경 확정, 트랜잭션 종료
ROLLBACK 시작 이후 변경 취소
SAVEPOINT name 부분 롤백 지점
ROLLBACK TO SAVEPOINT savepoint 이후만 취소
BEGIN;
  INSERT INTO audit_log (msg) VALUES ('step1');
  SAVEPOINT sp1;
  UPDATE accounts SET balance = balance - 50 WHERE id = 1;
  ROLLBACK TO SAVEPOINT sp1;  -- UPDATE only undone
COMMIT;                       -- audit_log row kept
  • DDL (PostgreSQL 일부) — 트랜잭션 블록 안에서도 implicit commit 될 수 있음 — DB별 확인
  • COMMIT 후 롤백 불가 — 보상 트랜잭션(compensating)은 앱 설계

5. 암시적 vs 명시적 트랜잭션

  암시적 (autocommit) 명시적
동작 문장마다 자동 COMMIT BEGINCOMMIT
기본 MySQL 기본 ON, psql도 ON 비즈니스 단위 묶을 때
위험 여러 DML이 각각 커밋 트랜잭션 안 잡고 장시간 hold
-- PostgreSQL
SHOW transaction_isolation;
SET autocommit = off;   -- client dependent

BEGIN;
-- business logic
COMMIT;
프레임워크 경계
JDBC setAutoCommit(false) + commit/rollback
Spring @Transactional — 메서드·클래스 단위
SQLAlchemy session.begin()
  • 읽기 전용 트랜잭션 — START TRANSACTION READ ONLY (PostgreSQL)
  • 장시간 트랜잭션 — 락·vacuum 지연 — 짧게 유지

6. 실무 체크리스트

항목 권장
경계 유스케이스 단위 — 이체·주문+재고
실패 catch 후 ROLLBACK, pool connection 반환
idempotency COMMIT 후 재시도는 중복 처리 설계
isolation 기본 READ COMMITTED — 올리기 전 이유 필요
분산 단일 DB 트랜잭션 vs saga — Architecture 분산 패턴
-- in-flight transaction (PostgreSQL)
SELECT pid, state, xact_start, query
FROM pg_stat_activity
WHERE state != 'idle';

7. 정리

  • 트랜잭션 = 논리 작업 단위 — 원자적 커밋 또는 롤백
  • ACID — A(전무전부), C(제약·불변식), I(동시 격리), D(커밋 후 유지)
  • COMMIT·ROLLBACK·SAVEPOINT로 경계·부분 취소
  • autocommit 끄고 명시적 경계 — ORM·서비스 레이어와 일치
  • 격리 수준·동시성 이상·WAL은 이후 편

다음에 다룰 것

  • 동시성 제어
  • Lost Update, Dirty Read, 격리 수준

해당 내용은 Database System Concepts, 7/E (Avraham Silberschatz, Henry F. Korth, S. Sudarshan) 의 내용을 기반으로 합니다.

'데이터베이스 따라잡기' 카테고리의 다른 글

데드락과 타임아웃  (0) 2026.06.28
동시성 제어  (0) 2026.06.27
실행 계획 읽기  (0) 2026.06.25
인덱스 구조  (0) 2026.06.24
디스크와 페이지  (0) 2026.06.23