Post

데이터베이스 트랜잭션과 ACID 원칙

데이터베이스 트랜잭션과 ACID 원칙

🔄 데이터베이스 트랜잭션이란?

트랜잭션은 데이터베이스의 상태를 변화시키는 하나의 논리적 작업 단위입니다. 트랜잭션은 여러 개의 연산을 포함할 수 있으며, 이 연산들은 모두 성공적으로 실행되거나 전혀 실행되지 않아야 합니다.

트랜잭션의 주요 특징

  • 원자성(Atomicity): 트랜잭션 내의 모든 연산은 전부 실행되거나 전혀 실행되지 않아야 합니다.
  • 일관성(Consistency): 트랜잭션 실행 전후로 데이터베이스는 일관된 상태를 유지해야 합니다.
  • 격리성(Isolation): 동시에 실행되는 트랜잭션들은 서로 영향을 미치지 않아야 합니다.
  • 지속성(Durability): 성공적으로 완료된 트랜잭션의 결과는 영구적으로 반영되어야 합니다.

트랜잭션의 상태

Image 사진출처

트랜잭션은 실행 과정에서 다음과 같은 상태를 거칩니다:

  • 활동(Active): 트랜잭션이 실행 중인 상태
  • 부분 완료(Partially Committed): 마지막 연산까지 실행했지만 아직 커밋되지 않은 상태
  • 완료(Committed): 트랜잭션이 성공적으로 완료되어 데이터베이스에 반영된 상태
  • 실패(Failed): 오류가 발생하여 트랜잭션 실행이 중단된 상태
  • 철회(Aborted): 트랜잭션이 취소되고 데이터베이스가 원래 상태로 복구된 상태

현업 실무에서의 활용

현업에서는 트랜잭션을 통해 데이터 무결성을 보장합니다. 예를 들어, 은행 시스템에서 계좌 이체 시 출금과 입금이 모두 성공적으로 이루어지거나 아예 이루어지지 않도록 하여 금액 불일치를 방지합니다.


⚛️ ACID 원칙

Image

사진출처

ACID는 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 4가지 특성의 약자입니다. 이 원칙은 데이터베이스 시스템의 신뢰성을 보장하는 핵심 요소입니다.

1. 원자성(Atomicity)

원자성은 트랜잭션의 연산들이 모두 성공적으로 실행되거나 전혀 실행되지 않는 “all or nothing” 특성을 의미합니다.

원자성의 핵심 개념

  • 트랜잭션은 분할할 수 없는 최소 단위입니다.
  • 부분적 실행은 허용되지 않습니다.
  • 오류 발생 시 롤백(rollback)을 통해 트랜잭션 시작 전 상태로 복구됩니다.

원자성 구현 방법

  • 로그 기반 복구(Log-based Recovery): 트랜잭션 실행 전 상태를 로그에 기록하여 실패 시 복구합니다.
  • 섀도우 페이징(Shadow Paging): 변경 사항을 임시 페이지에 저장하고 성공 시에만 실제 데이터베이스에 반영합니다.

예시 코드 (SQL)

1
2
3
4
5
6
7
8
9
10
11
BEGIN TRANSACTION;
    UPDATE accounts SET balance = balance - 1000 WHERE account_id = 'A';
    UPDATE accounts SET balance = balance + 1000 WHERE account_id = 'B';
    
    -- 조건 검사 (잔액이 음수가 되면 롤백)
    IF (SELECT balance FROM accounts WHERE account_id = 'A') < 0 THEN
        ROLLBACK;
    ELSE
        COMMIT;
    END IF;
END;

현업 실무에서의 활용

금융 시스템에서는 원자성을 통해 송금 과정에서 출금은 성공했으나 입금이 실패하는 상황을 방지합니다. 예를 들어, 은행 간 이체 시스템은 두 계좌의 업데이트가 모두 성공적으로 이루어지거나 전혀 이루어지지 않도록 보장합니다.

2. 일관성(Consistency)

일관성은 트랜잭션 실행 전후로 데이터베이스가 일관된 상태를 유지해야 함을 의미합니다. 즉, 트랜잭션은 데이터베이스의 무결성 제약조건을 위반하지 않아야 합니다.

일관성의 핵심 개념

  • 트랜잭션은 데이터베이스를 한 일관된 상태에서 다른 일관된 상태로 변환합니다.
  • 무결성 제약조건(기본 키, 외래 키, 도메인 제약 등)이 항상 유지됩니다.
  • 데이터 타입, 범위, 관계 등의 규칙이 준수됩니다.

일관성 보장 방법

  • 제약 조건(Constraints): 기본 키, 외래 키, CHECK 제약 등을 통해 데이터 일관성을 강제합니다.
  • 트리거(Triggers): 특정 이벤트 발생 시 자동으로 실행되는 코드로 일관성을 유지합니다.
  • 저장 프로시저(Stored Procedures): 미리 정의된 로직을 통해 일관된 데이터 처리를 보장합니다.

예시 코드 (SQL)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- 일관성을 위한 제약조건 설정
CREATE TABLE accounts (
    account_id VARCHAR(10) PRIMARY KEY,
    balance DECIMAL(10,2) CHECK (balance >= 0), -- 잔액은 항상 0 이상
    customer_id INT NOT NULL,
    FOREIGN KEY (customer_id) REFERENCES customers(id)
);

-- 트랜잭션 내에서 일관성 유지
BEGIN TRANSACTION;
    UPDATE accounts SET balance = balance - 1000 WHERE account_id = 'A';
    -- 일관성 검사 (잔액이 음수가 되면 롤백)
    IF (SELECT balance FROM accounts WHERE account_id = 'A') < 0 THEN
        ROLLBACK;
    ELSE
        UPDATE accounts SET balance = balance + 1000 WHERE account_id = 'B';
        COMMIT;
    END IF;
END;

현업 실무에서의 활용

전자상거래 시스템에서는 일관성을 통해 재고 관리의 정확성을 보장합니다. 예를 들어, 주문 처리 시 재고 수량이 음수가 되지 않도록 하며, 주문-결제-배송 상태 간의 논리적 일관성을 유지합니다.

3. 격리성(Isolation)

격리성은 동시에 실행되는 트랜잭션들이 서로 영향을 미치지 않도록 보장하는 특성입니다. 각 트랜잭션은 다른 트랜잭션의 중간 결과를 볼 수 없어야 합니다.

격리성의 핵심 개념

  • 동시 실행되는 트랜잭션들은 서로 독립적으로 동작합니다.
  • 트랜잭션의 중간 상태는 다른 트랜잭션에게 노출되지 않습니다.
  • 동시성 제어 기법을 통해 구현됩니다.

격리 수준(Isolation Levels)

  1. READ UNCOMMITTED: 가장 낮은 격리 수준으로, 커밋되지 않은 데이터도 읽을 수 있습니다(Dirty Read 발생).
  2. READ COMMITTED: 커밋된 데이터만 읽을 수 있습니다(Dirty Read 방지).
  3. REPEATABLE READ: 트랜잭션 내에서 같은 쿼리를 여러 번 실행해도 동일한 결과를 보장합니다(Non-repeatable Read 방지).
  4. SERIALIZABLE: 가장 높은 격리 수준으로, 트랜잭션들이 순차적으로 실행되는 것과 동일한 결과를 보장합니다(Phantom Read 방지).

Image 사진출처

동시성 문제

  • Dirty Read: 커밋되지 않은 데이터를 읽는 현상
  • Non-repeatable Read: 같은 쿼리를 여러 번 실행했을 때 다른 결과가 나오는 현상
  • Phantom Read: 트랜잭션 실행 중 다른 트랜잭션이 새 행을 삽입하여 이전에 없던 행이 조회되는 현상

격리성 구현 방법

  • 락킹(Locking): 공유 락(Shared Lock)과 배타적 락(Exclusive Lock)을 사용하여 동시 접근을 제어합니다.
  • 다중 버전 동시성 제어(MVCC): 데이터의 여러 버전을 유지하여 읽기 작업이 쓰기 작업을 차단하지 않도록 합니다.
  • 타임스탬프 기반 프로토콜: 트랜잭션에 타임스탬프를 부여하여 실행 순서를 결정합니다.

예시 코드 (SQL)

1
2
3
4
5
6
7
8
9
10
11
12
13
-- 격리 수준 설정
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

BEGIN TRANSACTION;
    -- 계좌 A의 잔액 조회
    SELECT balance FROM accounts WHERE account_id = 'A';
    
    -- 계좌 A에서 출금
    UPDATE accounts SET balance = balance - 1000 WHERE account_id = 'A';
    
    -- 계좌 B에 입금
    UPDATE accounts SET balance = balance + 1000 WHERE account_id = 'B';
COMMIT;

현업 실무에서의 활용

항공권 예약 시스템에서는 격리성을 통해 동시 예약 충돌을 방지합니다. 예를 들어, 두 사용자가 동시에 같은 좌석을 예약하려 할 때, 트랜잭션 격리를 통해 한 사용자의 예약이 완료된 후에만 다른 사용자의 예약 가능 여부가 결정됩니다.

4. 지속성(Durability)

지속성은 성공적으로 완료된(커밋된) 트랜잭션의 결과가 시스템 장애가 발생하더라도 영구적으로 반영되어야 함을 의미합니다.

지속성의 핵심 개념

  • 커밋된 트랜잭션의 변경사항은 영구적으로 저장됩니다.
  • 시스템 장애, 정전, 하드웨어 오류 등이 발생해도 데이터는 보존됩니다.
  • 복구 메커니즘을 통해 구현됩니다.

지속성 구현 방법

  • 트랜잭션 로그(Transaction Log): 모든 변경사항을 로그에 기록하여 장애 발생 시 복구합니다.
  • 체크포인트(Checkpoint): 주기적으로 데이터베이스의 일관된 상태를 디스크에 저장합니다.
  • 백업 및 복구(Backup & Recovery): 정기적인 백업과 복구 절차를 통해 데이터 손실을 방지합니다.

예시 (데이터베이스 설정)

1
2
3
4
5
6
7
8
9
-- MySQL에서 InnoDB 스토리지 엔진 사용 (지속성 보장)
CREATE TABLE accounts (
    account_id VARCHAR(10) PRIMARY KEY,
    balance DECIMAL(10,2)
) ENGINE=InnoDB;

-- PostgreSQL에서 WAL(Write-Ahead Logging) 설정
ALTER SYSTEM SET wal_level = 'replica';
ALTER SYSTEM SET archive_mode = 'on';

현업 실무에서의 활용

의료 정보 시스템에서는 지속성을 통해 환자 데이터의 안전한 보존을 보장합니다. 예를 들어, 전자 의무 기록(EMR) 시스템은 트랜잭션 로그와 백업을 통해 시스템 장애 시에도 중요한 의료 기록이 손실되지 않도록 합니다.


🔄 ACID와 NoSQL 데이터베이스

전통적인 관계형 데이터베이스(RDBMS)는 ACID 원칙을 엄격히 준수하지만, NoSQL 데이터베이스는 확장성과 성능을 위해 ACID 특성의 일부를 완화하는 경우가 많습니다.

NoSQL과 BASE 원칙

NoSQL 데이터베이스는 종종 ACID 대신 BASE(Basically Available, Soft state, Eventually consistent) 원칙을 따릅니다:

  • 기본적인 가용성(Basically Available): 시스템은 항상 응답해야 합니다.
  • 소프트 상태(Soft state): 시스템 상태는 시간이 지남에 따라 변할 수 있습니다.
  • 최종적 일관성(Eventually consistent): 시스템은 일정 시간이 지나면 일관된 상태에 도달합니다.

주요 NoSQL 데이터베이스와 ACID 지원

데이터베이스 유형예시ACID 지원 수준
문서 저장소MongoDB단일 문서 수준에서 ACID 지원, 다중 문서 트랜잭션 제한적 지원
키-값 저장소Redis단일 작업 수준에서 원자성 지원, 완전한 ACID는 미지원
컬럼 저장소Cassandra행 수준에서 원자성 지원, 완전한 ACID는 미지원
그래프 데이터베이스Neo4j완전한 ACID 트랜잭션 지원

CAP 이론과 ACID

CAP 이론은 분산 시스템이 일관성(Consistency), 가용성(Availability), 분할 내성(Partition tolerance) 세 가지 속성 중 동시에 두 가지만 만족할 수 있다고 설명합니다.

  • CP 시스템: 일관성과 분할 내성을 우선시 (예: HBase)
  • AP 시스템: 가용성과 분할 내성을 우선시 (예: Cassandra)
  • CA 시스템: 일관성과 가용성을 우선시 (예: 단일 노드 RDBMS)

Image 사진출처

현업 실무에서의 활용

대규모 소셜 미디어 플랫폼에서는 CAP 이론을 고려한 데이터베이스 선택이 중요합니다. 예를 들어, 페이스북은 메시지 전송 시스템에서 가용성과 분할 내성을 우선시하는 AP 시스템을 채택하여 일시적인 일관성 문제가 있더라도 서비스가 중단되지 않도록 합니다.


실무에서의 ACID 적용 사례

ACID 원칙은 다양한 산업 분야에서 중요하게 적용되고 있습니다. 실제 비즈니스 환경에서 ACID가 어떻게 활용되는지 살펴보겠습니다.

금융 시스템

금융 거래는 ACID 원칙이 가장 엄격하게 적용되는 영역입니다.

사례: 은행 송금 시스템

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
BEGIN TRANSACTION;
    -- 출금 계좌에서 금액 차감
    UPDATE accounts SET balance = balance - 5000 WHERE account_id = '1001';
    
    -- 입금 계좌에 금액 추가
    UPDATE accounts SET balance = balance + 5000 WHERE account_id = '2001';
    
    -- 거래 기록 생성
    INSERT INTO transactions (from_account, to_account, amount, transaction_date)
    VALUES ('1001', '2001', 5000, CURRENT_TIMESTAMP);
    
    -- 잔액 검증
    IF (SELECT balance FROM accounts WHERE account_id = '1001') < 0 THEN
        ROLLBACK;
        INSERT INTO transaction_logs (message, status) 
        VALUES ('잔액 부족으로 거래 취소', 'FAILED');
    ELSE
        COMMIT;
        INSERT INTO transaction_logs (message, status) 
        VALUES ('거래 성공', 'SUCCESS');
    END IF;
END;

적용 포인트

  • 원자성: 송금 과정의 모든 단계(출금, 입금, 기록)가 함께 성공하거나 실패합니다.
  • 일관성: 모든 계좌 잔액은 항상 0 이상이어야 합니다.
  • 격리성: 동시에 발생하는 다른 송금 작업과 충돌하지 않습니다.
  • 지속성: 송금이 완료되면 시스템 장애가 발생해도 데이터가 유지됩니다.

전자상거래 플랫폼

온라인 쇼핑몰에서는 주문 처리 과정에서 ACID 원칙이 중요합니다.

사례: 주문 처리 시스템

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
BEGIN TRANSACTION;
    -- 재고 확인
    IF (SELECT stock FROM products WHERE product_id = 100) < 2 THEN
        ROLLBACK;
        SELECT '재고 부족' AS message;
    ELSE
        -- 재고 감소
        UPDATE products SET stock = stock - 2 WHERE product_id = 100;
        
        -- 주문 생성
        INSERT INTO orders (customer_id, order_date, status)
        VALUES (500, CURRENT_TIMESTAMP, 'PENDING');
        
        -- 주문 상세 정보 추가
        INSERT INTO order_items (order_id, product_id, quantity, price)
        VALUES (LAST_INSERT_ID(), 100, 2, (SELECT price FROM products WHERE product_id = 100));
        
        COMMIT;
        SELECT '주문 성공' AS message;
    END IF;
END;

적용 포인트

  • 원자성: 재고 확인, 재고 감소, 주문 생성이 모두 함께 처리됩니다.
  • 일관성: 재고는 항상 0 이상으로 유지됩니다.
  • 격리성: 동일 상품에 대한 여러 주문이 서로 간섭하지 않습니다.
  • 지속성: 주문이 완료되면 영구적으로 기록됩니다.

의료 정보 시스템

환자 데이터를 다루는 의료 시스템에서는 데이터 정확성이 생명과 직결됩니다.

사례: 처방전 발행 시스템

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
BEGIN TRANSACTION;
    -- 환자 정보 확인
    SELECT patient_id, allergies FROM patients WHERE patient_id = 1234;
    
    -- 약물 상호작용 확인
    IF EXISTS (
        SELECT 1 FROM patient_medications pm
        JOIN medication_interactions mi ON pm.medication_id = mi.medication1_id
        WHERE pm.patient_id = 1234 AND mi.medication2_id = 567
    ) THEN
        ROLLBACK;
        INSERT INTO alert_logs (patient_id, message, alert_type)
        VALUES (1234, '약물 상호작용 위험', 'HIGH');
    ELSE
        -- 처방전 생성
        INSERT INTO prescriptions (patient_id, doctor_id, prescription_date)
        VALUES (1234, 5678, CURRENT_TIMESTAMP);
        
        -- 처방 약물 추가
        INSERT INTO prescription_medications (prescription_id, medication_id, dosage, instructions)
        VALUES (LAST_INSERT_ID(), 567, '10mg', '하루 2회 식후 복용');
        
        COMMIT;
    END IF;
END;

적용 포인트

  • 원자성: 약물 상호작용 확인과 처방전 발행이 하나의 단위로 처리됩니다.
  • 일관성: 환자 안전을 위한 규칙(약물 상호작용 방지)이 항상 지켜집니다.
  • 격리성: 여러 의사가 동시에 같은 환자에게 처방해도 충돌이 발생하지 않습니다.
  • 지속성: 처방 정보는 시스템 장애 후에도 보존됩니다.

🚧 ACID의 한계와 대안

ACID 원칙은 데이터 무결성을 보장하는 강력한 방법이지만, 대규모 분산 시스템에서는 성능과 확장성 측면에서 한계가 있습니다.

ACID의 한계점

  1. 성능 오버헤드: 엄격한 ACID 준수는 락킹과 동기화로 인한 성능 저하를 초래할 수 있습니다.
  2. 확장성 제한: 수평적 확장(Horizontal Scaling)이 어려워질 수 있습니다.
  3. 분산 환경 적용의 어려움: 지리적으로 분산된 시스템에서 완전한 ACID 보장이 어렵습니다.

BASE 모델

BASE(Basically Available, Soft state, Eventually consistent)는 NoSQL 데이터베이스에서 주로 사용되는 대안적 모델입니다.

BASE의 특징

  • 기본적인 가용성(Basically Available): 시스템은 항상 응답을 반환합니다.
  • 소프트 상태(Soft state): 시스템 상태는 시간에 따라 변할 수 있으며, 외부 입력이 없어도 변경될 수 있습니다.
  • 최종적 일관성(Eventually consistent): 시스템은 일정 시간이 지나면 일관된 상태에 도달합니다.

BASE vs ACID 비교

특성ACIDBASE
일관성즉시 일관성최종적 일관성
가용성일관성 우선가용성 우선
확장성제한적높음
적합한 환경금융, 의료 등 중요 데이터소셜 미디어, 콘텐츠 배포 등

실용적인 접근법: ACID와 BASE의 혼합

많은 현대 시스템은 ACID와 BASE를 상황에 맞게 혼합하여 사용합니다.

사례: 전자상거래 플랫폼의 하이브리드 접근법

  • ACID 적용: 주문 처리, 결제, 재고 관리 등 핵심 비즈니스 로직
  • BASE 적용: 제품 리뷰, 추천 시스템, 사용자 활동 로그 등
1
2
3
4
5
6
7
8
9
10
11
-- ACID 트랜잭션 (주문 처리)
BEGIN TRANSACTION;
    UPDATE inventory SET stock = stock - 1 WHERE product_id = 123;
    INSERT INTO orders (customer_id, product_id, quantity) VALUES (456, 123, 1);
    INSERT INTO payments (order_id, amount, status) VALUES (LAST_INSERT_ID(), 99.99, 'COMPLETED');
COMMIT;

-- BASE 접근 (비동기 처리)
INSERT INTO analytics_queue (event_type, data, created_at)
VALUES ('NEW_ORDER', JSON_OBJECT('customer_id', 456, 'product_id', 123), CURRENT_TIMESTAMP);
-- 별도의 비동기 프로세스가 큐에서 이벤트를 처리하고 분석 데이터베이스에 저장
This post is licensed under CC BY 4.0 by the author.