전체 목록
데이터베이스Medium#095

트랜잭션의 ACID 속성에 대해 각각 설명해주세요.

#DB#ACID#트랜잭션#데이터베이스

답변 포인트

원자성, 일관성, 격리성, 지속성의 영어 첫 글자입니다.

정답 및 해설

빠른 요약

ACID는 트랜잭션의 신뢰성을 보장하는 4가지 속성입니다. A - 원자성(Atomicity): 트랜잭션의 모든 연산은 전부 완료되거나 전부 취소(rollback)되어야 합니다.

ACID는 데이터베이스 트랜잭션의 신뢰성을 보장하는 4가지 핵심 속성입니다. 트랜잭션이란 하나의 논리적 작업 단위로, 여러 데이터베이스 연산을 묶어 전부 성공하거나 전부 실패하도록 보장합니다. ACID 속성을 통해 데이터베이스는 하드웨어 오류, 동시 접근, 소프트웨어 버그 등의 상황에서도 데이터 무결성을 유지합니다.

트랜잭션이란?

SQL
-- 계좌 이체 예시: 두 작업이 하나의 트랜잭션으로 처리되어야 함
BEGIN TRANSACTION;

UPDATE accounts
SET balance = balance - 10000
WHERE account_id = 'A001';  -- A 계좌에서 출금

UPDATE accounts
SET balance = balance + 10000
WHERE account_id = 'B001';  -- B 계좌에 입금

COMMIT;  -- 모두 성공하면 반영

-- 중간에 오류 발생 시
ROLLBACK;  -- 모든 변경사항 취소

출금만 되고 입금이 안 되면 심각한 문제가 발생합니다. 트랜잭션과 ACID 속성이 이를 방지합니다.

A - 원자성 (Atomicity)

정의

트랜잭션 내의 모든 연산은 **전부 완료(Commit)되거나 전부 취소(Rollback)**되어야 합니다. 부분적으로 실행된 상태는 존재할 수 없습니다("All or Nothing").

예시

SQL
-- 원자성 보장 예시
BEGIN TRANSACTION;

UPDATE orders SET status = 'PROCESSING' WHERE order_id = 101;

INSERT INTO order_history (order_id, status, changed_at)
VALUES (101, 'PROCESSING', NOW());

UPDATE inventory SET stock = stock - 1 WHERE product_id = 'P001';

-- 재고가 0 미만이 되면?
-- → 오류 발생 → ROLLBACK → orders, order_history 변경도 모두 취소
-- → 데이터 일관성 유지

COMMIT;

구현 방법 (DBMS 내부)

데이터베이스
Undo Log ( ):
-       Undo Log 
-    Undo Log    

Redo Log ( ):
-   Redo Log 
-      Redo Log  

C - 일관성 (Consistency)

정의

트랜잭션 전과 후 모두 데이터베이스가 정의된 모든 **제약 조건(Constraint)**을 만족하는 유효한 상태여야 합니다.

예시

SQL
-- 일관성 제약 조건들
CREATE TABLE accounts (
  account_id VARCHAR(20) PRIMARY KEY,
  balance    DECIMAL(15, 2) NOT NULL,
  CONSTRAINT balance_positive CHECK (balance >= 0)  -- 잔액은 0 이상
);

CREATE TABLE orders (
  order_id   INT PRIMARY KEY,
  user_id    INT NOT NULL,
  amount     DECIMAL(10, 2) NOT NULL,
  FOREIGN KEY (user_id) REFERENCES users(id)  -- 참조 무결성
);

-- 일관성 위반 시도 (거부됨)
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 50000 WHERE account_id = 'A001';
-- 잔액이 30000원인 계좌에서 50000원 출금 시도
-- → CHECK 제약 위반: balance = -20000 < 0
-- → 트랜잭션 자동 롤백
COMMIT;

일관성의 책임 범위

데이터베이스
DBMS  :
 PRIMARY KEY  
 FOREIGN KEY  
 NOT NULL 
 CHECK  
 UNIQUE 

   :
   (:   )
   
   

I - 격리성 (Isolation)

정의

동시에 실행 중인 여러 트랜잭션이 서로의 중간 상태를 볼 수 없어야 합니다. 각 트랜잭션은 독립적으로 실행되는 것처럼 보여야 합니다.

격리성 부재 시 발생하는 문제들

SQL
-- 1. Dirty Read (커밋되지 않은 데이터 읽기)
T1: BEGIN;
T1: UPDATE accounts SET balance = 100000 WHERE id = 'A001';
-- T1이 아직 커밋하지 않은 상태에서
T2: SELECT balance FROM accounts WHERE id = 'A001';  -- 100000 읽음 (더티 리드!)
T1: ROLLBACK;  -- T1 롤백 → T2가 읽은 데이터는 존재하지 않는 데이터

-- 2. Non-repeatable Read (반복 읽기 불일치)
T1: SELECT balance FROM accounts WHERE id = 'A001';  -- 50000 읽음
T2: UPDATE accounts SET balance = 80000 WHERE id = 'A001';
T2: COMMIT;
T1: SELECT balance FROM accounts WHERE id = 'A001';  -- 80000 읽음 (값이 달라짐!)

-- 3. Phantom Read (유령 데이터)
T1: SELECT COUNT(*) FROM orders WHERE amount > 10000;  -- 5개
T2: INSERT INTO orders (amount) VALUES (15000);
T2: COMMIT;
T1: SELECT COUNT(*) FROM orders WHERE amount > 10000;  -- 6개 (幽靈 행 등장!)

격리 수준 (Isolation Level)

SQL
-- 격리 수준 설정
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
격리 수준Dirty ReadNon-repeatable ReadPhantom Read성능
READ UNCOMMITTED발생 가능발생 가능발생 가능최고
READ COMMITTED방지발생 가능발생 가능높음
REPEATABLE READ방지방지발생 가능보통
SERIALIZABLE방지방지방지최저
데이터베이스
 DBMS :
- MySQL InnoDB: REPEATABLE READ
- PostgreSQL: READ COMMITTED
- Oracle: READ COMMITTED
- SQL Server: READ COMMITTED

격리 구현 방법

데이터베이스
1. Lock-based Concurrency Control
   -  (Shared Lock):  ,     
   -  (Exclusive Lock):  ,    

2. MVCC (Multi-Version Concurrency Control)
   - PostgreSQL, MySQL InnoDB 
   -        
   -         

D - 지속성 (Durability)

정의

한 번 커밋(Commit)된 트랜잭션의 결과는 시스템 장애(정전, 크래시 등)가 발생해도 영구적으로 유지됩니다.

구현 방법

데이터베이스
WAL (Write-Ahead Logging):
1.     (WAL) 
2.      
3.  : WAL    (Redo)

:
COMMIT  
    
Redo Log(WAL)   ( fsync)
    
COMMIT   (   )
    
()    
SQL
-- PostgreSQL의 지속성 관련 설정
-- synchronous_commit: 로그가 디스크에 기록될 때까지 대기 여부
-- off로 설정 시 성능 향상되지만 지속성 약해짐 (데이터 유실 가능)
SET synchronous_commit = ON;  -- 기본값, 지속성 보장

실무에서의 ACID

분산 데이터베이스와 ACID

데이터베이스
 DB: ACID   ( )
 DB: ACID  

CAP :
- Consistency(), Availability(), Partition tolerance( )
-      
- NoSQL (MongoDB, Cassandra )  ACID   / 

BASE (NoSQL ):
- Basically Available:  
- Soft state:     
- Eventually consistent:   

트랜잭션 실무 팁

SQL
-- 긴 트랜잭션은 피해야 합니다
-- ❌ 나쁜 예: 트랜잭션 내에서 외부 API 호출
BEGIN;
UPDATE orders SET status = 'PROCESSING' WHERE id = 101;
-- 이 시점에서 orders 테이블에 잠금 유지!
-- 외부 API 호출 (수 초 소요 가능)
CALL external_payment_api();
UPDATE orders SET status = 'PAID' WHERE id = 101;
COMMIT;
-- → 잠금 대기 증가, 데드락 위험

-- ✅ 좋은 예: 외부 호출을 트랜잭션 밖으로
-- 1. 상태를 PENDING으로 저장
-- 2. 트랜잭션 종료
-- 3. 외부 API 호출
-- 4. 결과에 따라 새 트랜잭션으로 상태 업데이트

-- 저장점(Savepoint) 활용
BEGIN;
SAVEPOINT before_update;
UPDATE products SET stock = stock - 1 WHERE id = 'P001';
-- 문제 발생 시
ROLLBACK TO SAVEPOINT before_update;
-- 일부만 롤백, 전체 트랜잭션은 유지
COMMIT;

정리

속성의미보장하는 것구현 기술
Atomicity (원자성)All or Nothing부분 실행 없음Undo Log, Rollback
Consistency (일관성)제약 조건 항상 만족데이터 무결성제약 조건, 트리거
Isolation (격리성)트랜잭션 간 독립성동시성 문제 방지Lock, MVCC
Durability (지속성)커밋 후 영구 보존장애 후 복구WAL, Redo Log

핵심: ACID는 데이터베이스가 신뢰할 수 있는 트랜잭션 처리를 위해 반드시 보장해야 하는 속성들입니다. 특히 계좌 이체, 주문 처리 등 데이터 무결성이 중요한 금융/커머스 시스템에서 필수적입니다.

관련 질문

같은 카테고리/태그 기준