C

트랜잭션과 ACID란? 데이터베이스 핵심 개념 정리

2026-05-21 · Database · 트랜잭션 · ACID · 입문

트랜잭션과 ACID란 무엇인가

트랜잭션이란 데이터베이스에서 하나의 논리적 작업 단위로 묶이는 여러 연산의 집합입니다. 대표 예시는 계좌 이체입니다. "A 계좌에서 1만 원 빼기"와 "B 계좌에 1만 원 더하기"는 따로따로 성공하면 안 됩니다. 둘 다 성공하거나, 둘 다 없던 일이 되어야 합니다. 이렇게 "전부 아니면 전무"를 보장하는 단위가 트랜잭션이고, 그 품질 기준을 정리한 것이 ACID입니다.

ACID는 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 지속성(Durability)의 머리글자입니다. 이 글에서는 트랜잭션과 ACID란 무엇인지 예제와 함께 정리합니다.

트랜잭션 문법: COMMIT과 ROLLBACK

트랜잭션은 BEGIN(또는 START TRANSACTION)으로 시작해, 성공하면 COMMIT으로 확정하고, 문제가 생기면 ROLLBACK으로 되돌립니다.

START TRANSACTION;

UPDATE accounts SET balance = balance - 10000 WHERE id = 1;  -- A 출금
UPDATE accounts SET balance = balance + 10000 WHERE id = 2;  -- B 입금

COMMIT;   -- 두 작업을 한꺼번에 확정

만약 두 번째 UPDATE에서 오류가 나면 다음처럼 되돌립니다.

START TRANSACTION;

UPDATE accounts SET balance = balance - 10000 WHERE id = 1;
-- 오류 발생!

ROLLBACK;  -- 출금까지 모두 취소되어 원래 상태로 복구

ACID 네 가지 속성

원자성(Atomicity)

트랜잭션 안의 모든 연산은 전부 반영되거나 전부 취소됩니다. 이체에서 출금만 되고 입금이 안 되는 어중간한 상태는 허용되지 않습니다. 이를 보장하는 핵심 장치가 ROLLBACK입니다.

일관성(Consistency)

트랜잭션이 끝난 뒤에도 데이터베이스는 정의된 규칙(제약 조건, 무결성)을 항상 만족해야 합니다. 예를 들어 "잔액은 음수가 될 수 없다"는 제약이 있다면, 그 규칙을 깨는 트랜잭션은 커밋되지 않고 실패합니다.

격리성(Isolation)

여러 트랜잭션이 동시에 실행되어도 서로의 중간 결과에 간섭하지 않아야 합니다. 마치 혼자 실행되는 것처럼 보여야 한다는 뜻입니다. 격리 수준이 낮으면 다른 트랜잭션의 미완성 데이터를 읽는 문제가 생길 수 있습니다.

지속성(Durability)

한번 COMMIT된 데이터는 시스템이 갑자기 꺼지거나 장애가 나도 사라지지 않습니다. 데이터베이스는 로그(WAL 등)에 변경을 먼저 기록해 이를 보장합니다.

ACID 요약표

속성의미보장하는 것
Atomicity원자성전부 또는 전무
Consistency일관성규칙 위반 없는 상태 유지
Isolation격리성동시 실행 간 간섭 차단
Durability지속성커밋 후 영구 보존

격리 수준과 동시성 문제

격리성은 성능과 트레이드오프 관계라, SQL 표준은 네 가지 격리 수준을 제공합니다. 수준이 높을수록 안전하지만 동시 처리량은 떨어집니다.

격리 수준막아주는 문제
READ UNCOMMITTED(거의 없음) Dirty Read 허용
READ COMMITTEDDirty Read 방지
REPEATABLE READDirty Read, Non-repeatable Read 방지
SERIALIZABLEPhantom Read까지 방지(가장 엄격)

여기서 Dirty Read는 아직 커밋되지 않은 데이터를 읽는 것, Non-repeatable Read는 같은 행을 두 번 읽었는데 값이 달라지는 것, Phantom Read는 같은 조건으로 조회했는데 행 개수가 달라지는 것을 말합니다.

실전 팁

트랜잭션은 가능한 한 짧게 유지하세요. 트랜잭션이 길어지면 그동안 잠금(lock)이 유지되어 다른 작업이 대기하고, 교착 상태(deadlock) 위험도 커집니다. 또한 외부 API 호출이나 사용자 입력 대기처럼 오래 걸리는 작업은 트랜잭션 안에 넣지 마세요. 대부분의 백엔드 프레임워크는 @Transactional 같은 선언적 트랜잭션을 제공하므로, 메서드 단위로 명확히 경계를 잡는 것이 좋습니다.

흔한 실수

1. COMMIT을 빠뜨리기. 자동 커밋이 꺼진 환경에서 COMMIT 없이 연결을 끊으면 변경이 전부 롤백됩니다. "분명 UPDATE했는데 데이터가 그대로"라면 커밋 여부부터 확인하세요.

2. 예외 처리에서 ROLLBACK 누락. 중간에 예외가 났는데 롤백하지 않으면 일부만 반영된 깨진 상태가 남습니다. 예외 발생 시 반드시 롤백되도록 처리해야 합니다.

자주 묻는 질문

Q1. SELECT만 하는데도 트랜잭션이 필요한가요?

단순 조회 하나면 굳이 명시적 트랜잭션이 필요 없습니다. 다만 여러 번 조회 사이에 일관된 스냅샷이 필요하다면 트랜잭션으로 묶어 격리 수준을 활용합니다.

Q2. 자동 커밋(auto-commit)이 뭔가요?

각 SQL 문이 실행 즉시 자동으로 커밋되는 모드입니다. 대부분의 DB 클라이언트가 기본으로 켜 둡니다. 여러 문을 한 트랜잭션으로 묶으려면 명시적으로 START TRANSACTION을 시작해야 합니다.

Q3. 격리 수준은 보통 무엇을 쓰나요?

MySQL(InnoDB)의 기본값은 REPEATABLE READ, PostgreSQL과 Oracle, SQL Server의 기본값은 READ COMMITTED입니다. 대부분의 웹 서비스는 READ COMMITTED 또는 REPEATABLE READ로 충분합니다.

트랜잭션과 ACID란? 데이터베이스 핵심 개념 정리 | CodeMaster 블로그 | CodeMaster