트랜잭션
트랜잭션의 원자성과 격리성을 구분하고, 1976년 잠금 이론부터 Gray·ACID·스냅샷 격리·PostgreSQL SSI까지 이어진 역사를 살펴본다.
· 마지막 업데이트: 2026-11-04 · 8 min read
개요
트랜잭션(transaction)은 관련된 데이터 조작을 하나의 작업 단위로 취급하는 개념이다. 계좌 이체에서 보내는 계좌의 잔액 감소와 받는 계좌의 잔액 증가를 따로 확정하면, 둘 사이의 장애로 돈이 사라지거나 늘어날 수 있다. 두 변경을 같은 작업의 일부로 묶으면 전부 확정하거나 전부 취소하는 기준을 세울 수 있다.
데이터베이스에서는 여러 문장으로 표현된 작업도 하나의 트랜잭션에 들어갈 수 있다. 작업이 성공해 결과를 확정하는 동작이 커밋(commit)이고, 진행 중인 변경을 취소하는 동작이 롤백(rollback)이다. 사용자에게 보이는 주문 한 건이 DB 트랜잭션 하나와 정확히 겹치는지는 애플리케이션이 경계를 어디에 두는지에 달려 있다.
묶어서 확정하는 성질만으로는 동시 실행을 설명하지 못한다. 두 사람이 같은 좌석을 동시에 예약하는 경우도 있고, 서로 다른 행을 바꾼 두 작업이 합쳐져 규칙 하나를 어기는 경우도 있다. 그래서 트랜잭션은 무엇을 한 번에 복구할지와 함께, 여러 작업이 겹칠 때 어떤 실행을 허용할지도 다룬다. 앞의 질문은 원자성, 뒤의 질문은 격리성으로 갈린다.
이 문서는 트랜잭션을 특정 DB의 BEGIN 문법보다는 장애를 견디는 데이터 처리 단위를 어떻게 정의할지의 문제로 다룬다. SQL 격리 수준과 MVCC는 그 개념을 구현하고 조정하는 과정에서 만나는 용어다.
연혁
1976년: K. P. Eswaran, J. N. Gray, R. A. Lorie, I. L. Traiger가 「The Notions of Consistency and Predicate Locks in a Database System」에서 트랜잭션·일관성·스케줄과 잠금의 관계를 형식화했다.1
1981년: Jim Gray가 「The Transaction Concept: Virtues and Limitations」에서 트랜잭션을 원자성·일관성·내구성을 가진 상태 변환으로 설명했다. 이미 발전하던 개념과 구현을 정리하면서 하위 트랜잭션, 오래 지속되는 작업처럼 남은 문제도 함께 논의했다.2
1983년: Theo Härder와 Andreas Reuter가 「Principles of Transaction-Oriented Database Recovery」에서 복구 기법을 같은 개념으로 비교하는 틀을 제시하고, 원자성·일관성·격리성·내구성을 ACID로 묶어 설명했다.3
1995년: Hal Berenson 등이 「A Critique of ANSI SQL Isolation Levels」에서 당시 SQL 격리 수준 정의의 모호함과 빠진 경우를 분석하고 스냅샷 격리를 다뤘다.4
2012년: Dan R. K. Ports와 Kevin Grittner가 「Serializable Snapshot Isolation in PostgreSQL」에서 PostgreSQL 9.1의 Serializable Snapshot Isolation(SSI) 구현 경험을 발표했다. 이 연도는 논문 발표 시점이다.5
공유 데이터와 직렬가능성 (1976)
여러 사용자가 같은 데이터를 다루면 작업 하나하나의 올바름과 전체 실행의 올바름이 갈라진다. 재고를 읽고 줄이는 절차는 따로 떼어 보면 맞아도, 두 작업이 서로의 읽기와 쓰기 사이에 끼어들면 결과가 달라진다.
Eswaran·Gray·Lorie·Traiger의 1976년 논문은 공유 데이터의 일관성과 실행 순서를 한 문제로 묶어, 어떤 잠금 규칙 아래에서 여러 작업을 섞어 실행해도 직렬 실행과 같은 결과를 얻는지 분석했다. 물리적인 레코드뿐 아니라 조건으로 지정한 데이터 집합을 보호하는 문제도 다뤘다.1 이 논문에서 트랜잭션은 SQL 명령 하나의 이름보다 넓은 작업 단위이고, 뒤이은 복구와 격리 논의도 무엇을 한 작업으로 보고 어떤 실행을 허용할지라는 두 질문을 이어받는다.
직렬가능성은 성공한 작업들의 효과가 어떤 직렬 순서로 실행한 결과와 같아야 한다는 요구다. 실제 구현은 작업을 겹쳐 실행하면서, 충돌하는 작업을 기다리게 하거나 중단시켜 이 요구를 맞출 수 있다.
상태 변환과 복구 범위 (1981)
Jim Gray의 1981년 논문은 동작을 비보호(unprotected)·보호(protected)·실제(real) 동작의 세 부류로 나눠 복구 범위를 구분한다. 비보호 동작은 트랜잭션이 중단돼도 되돌리거나 다시 실행할 필요가 없고, DB 변경 같은 보호 동작은 되돌리거나 다시 실행할 수 있어야 한다. 현금 배출 같은 실제 동작은 한 번 일어나면 되돌릴 수 없으므로 커밋할 때까지 미룬다.2 이 구분은 훗날 원격 서비스 호출이나 메시지 전달을 로컬 롤백과 어떻게 연결할지 이해하는 데도 쓰인다.
복구 시스템은 어떤 변경이 같은 작업에 속하고 무엇이 이미 확정됐는지 알아야 한다. 작업 경계와 커밋 기록이 제어 문법이면서 동시에 복구 판단의 근거가 되는 이유다.
ACID와 복구 기법의 공통 언어 (1983)
성질 | 다루는 문제 |
|---|---|
Atomicity, 원자성 | 일부 변경만 확정되는 일을 막고 작업의 전부 또는 취소를 정한다 |
Consistency, 일관성 | 선언한 무결성·업무 규칙을 유지하는 상태 변환을 요구한다 |
Isolation, 격리성 | 함께 실행되는 트랜잭션 사이의 관찰과 영향을 다룬다 |
Durability, 내구성 | 커밋된 결과를 저장·복구 계약에 따라 유지한다 |
- 성질
Atomicity, 원자성
- 다루는 문제
일부 변경만 확정되는 일을 막고 작업의 전부 또는 취소를 정한다
- 성질
Consistency, 일관성
- 다루는 문제
선언한 무결성·업무 규칙을 유지하는 상태 변환을 요구한다
- 성질
Isolation, 격리성
- 다루는 문제
함께 실행되는 트랜잭션 사이의 관찰과 영향을 다룬다
- 성질
Durability, 내구성
- 다루는 문제
커밋된 결과를 저장·복구 계약에 따라 유지한다
Härder와 Reuter의 1983년 논문은 로그와 체크포인트, 변경을 저장 장치에 반영하는 전략을 공통된 개념으로 비교한다. WAL은 변경된 데이터 페이지를 저장 장치에 쓰기 전에 복구에 필요한 로그를 먼저 영속화하는 규칙이다.36 일관성이 요구하는 업무 규칙은 스키마와 애플리케이션이 표현해야 한다. DB는 잘못 작성한 계산의 의도까지 알아내 주지 않는다.
1983년의 정리는 서로 다른 복구 구현을 같은 질문으로 비교할 공통 용어가 자리 잡은 과정을 보여준다.
SQL 격리 수준과 쓰기 왜곡 (1995)
SQL의 격리 수준은 dirty read, nonrepeatable read, phantom 같은 이상 현상으로 설명돼 왔다. Hal Berenson 등의 1995년 분석에서 드러나듯 안정적인 스냅샷을 읽는 것과 직렬가능성은 서로 다른 성질이다.4 같은 시점의 데이터를 읽더라도 서로 다른 행을 쓰는 두 트랜잭션이 함께 규칙을 깨뜨릴 수 있는데, 이 쓰기 왜곡을 보면 “같은 행을 덮어쓰지 않았다”만으로는 동시 실행이 올바른지 판정할 수 없다.
스냅샷 위의 직렬가능성 구현 (2012)
Dan R. K. Ports와 Kevin Grittner의 2012년 논문은 PostgreSQL 9.1의 SSI 구현이 제공하는 격리와 그 비용, 충돌 검사를 확인하는 근거로 쓰인다. 논문의 당직 예에서 두 트랜잭션은 각각 당직자 두 명을 읽은 뒤 자기 행만 근무 종료로 바꿀 수 있고, 스냅샷 격리에서는 쓰기 대상이 달라도 최종 당직자가 0명이 되는 실행이 가능하다. SSI는 읽기·쓰기 의존성을 추적해 직렬가능성을 깨뜨릴 수 있는 실행을 중단하는데, 거짓 양성 때문에 직렬가능한 실행이 중단될 수도 있다.5
MVCC는 여러 버전을 관리하는 기법이고, 어느 버전을 읽고 어떤 충돌을 거절할지는 격리 규칙이 정한다. PostgreSQL 18에서도 Read Committed·Repeatable Read·Serializable의 관찰 결과는 서로 다르며, 직렬화 실패가 나면 호출자가 실패한 트랜잭션 전체를 다시 판단해야 한다.7
서비스 간 업무
트랜잭션을 적용할 범위가 여러 서비스로 넓어지면 DB의 작업 단위와 사용자에게 보이는 업무의 길이가 달라진다. 한 DB 안의 주문과 재고는 로컬 트랜잭션에 넣을 수 있지만, 다른 서비스의 메일이나 결제까지 이어지는 업무에는 추가 계약이 필요하다.
분산 트랜잭션은 여러 참여자의 확정을 조정하고, 사가는 여러 단계와 보상 동작을 구성한다. 아웃박스는 업무 변경과 전달할 사건을 같은 DB에 같은 로컬 트랜잭션으로 기록한다. 이 방식들에서 Gray가 구분한 복구 범위의 문제를 서비스 아키텍처의 맥락으로 다시 읽을 수 있다. 각 방식의 의미를 비교하려면 한 DB의 롤백이 어디까지 책임지는지부터 정해야 한다.
원자성을 보여주는 작은 롤백 예제
아래 PostgreSQL 예제에서 재고 변경과 주문 기록은 같은 확정 범위에 있다. 예제는 두 쓰기를 함께 취소하는 동작만 확인하며, 동시 주문 API의 구현은 다루지 않는다.
CREATE TEMP TABLE stock (id integer PRIMARY KEY, quantity integer NOT NULL);
CREATE TEMP TABLE orders (id integer PRIMARY KEY, item_id integer NOT NULL);
INSERT INTO stock VALUES (1, 1);
BEGIN;
UPDATE stock SET quantity = quantity - 1 WHERE id = 1;
INSERT INTO orders VALUES (100, 1);
ROLLBACK;
SELECT quantity FROM stock WHERE id = 1;
SELECT count(*) FROM orders;
psql에서 파일을 문장 단위로 실행하면 마지막 조회는 재고 1, 주문 수 0을 돌려준다. 두 변경을 함께 취소했기 때문이다. 같은 위치에서 COMMIT하면 두 변경을 확정한다.
각주
- K. P. Eswaran·J. N. Gray·R. A. Lorie·I. L. Traiger, 「The Notions of Consistency and Predicate Locks in a Database System」, CACM 19(11), 1976. 저자 기관 서지와 초록. ↩
- Jim Gray, 「The Transaction Concept: Virtues and Limitations」, VLDB, 1981. 저자 제공 원문. ↩
- Theo Härder·Andreas Reuter, 「Principles of Transaction-Oriented Database Recovery」, ACM Computing Surveys 15(4), 1983, pp.287–317. 원문 사본. ↩
- Hal Berenson 외, 「A Critique of ANSI SQL Isolation Levels」, SIGMOD, 1995, §4.2 및 A5B. 연구기관 원문. ↩
- Dan R. K. Ports·Kevin Grittner, 「Serializable Snapshot Isolation in PostgreSQL」, PVLDB 5(12), 2012, pp.1850–1861, §1–2.1.1, §3.3. 출판기관 원문. ↩
- PostgreSQL 18, §28.3 “Write-Ahead Logging (WAL)”. 공식 문서. 데이터 파일 반영 전에 해당 WAL 레코드를 영속 저장소에 기록하는 순서를 설명한다. ↩
- PostgreSQL 18, §13.2 “Transaction Isolation”. 공식 문서. ↩