ZeroBase/CS

데이터베이스 트랜잭션 - ACID와 무결성

Red_Horse 2025. 9. 28. 19:39

트랜잭션은 데이터베이스에서 하나의 논리적 기능을 수행하기 위한 작업의 단위를 말하며, 데이터베이스에 접근하는 방법은 쿼리이므로, 여러 개의 쿼리들을 하나로 묶는 단위를 말합니다.

 

기본 개념

-- 트랜잭션 예시: 계좌 이체
BEGIN TRANSACTION;
    UPDATE accounts SET balance = balance - 1000 WHERE account_id = 'A';
    UPDATE accounts SET balance = balance + 1000 WHERE account_id = 'B';
COMMIT;

-- 모든 쿼리가 성공하면 커밋, 하나라도 실패하면 롤백
 
 
 

커밋과 롤백

 

커밋 (Commit)

여러 쿼리가 성공적으로 처리되었다고 확정하는 명령어입니다. 트랜잭션 단위로 수행되며 변경된 내용이 모두 영구적으로 저장되는 것을 말합니다.

 

롤백 (Rollback)

트랜잭션으로 처리한 하나의 묶음 과정을 일어나기 전으로 돌리는 일을 말합니다.

 

트랜잭션 처리 과정

1. BEGIN TRANSACTION
2. UPDATE/INSERT/DELETE 쿼리들 실행
3-a. 모든 쿼리 성공 → COMMIT → 영구 저장
3-b. 하나라도 실패 → ROLLBACK → 원상 복구
 
 

트랜잭션의 장점

  • 데이터의 무결성 보장
  • 데이터 변경 전에 변경 사항을 쉽게 확인 가능
  • 해당 작업을 그룹화 가능

주의사항

트랜잭션으로 묶는 로직에 외부 API 호출은 자제해야 합니다. 롤백을 고려해야 하기 때문입니다.

 

트랜잭션 전파 (Transaction Propagation)

 

트랜잭션을 수행할 때 커넥션 단위로 수행하기 때문에 커넥션 객체를 넘겨서 수행해야 합니다. 하지만 이를 매번 넘겨주기가 어렵고 번거롭습니다.

트랜잭션 전파는 커넥션을 직접 넘기지 않고도 여러 트랜잭션 관련 메서드의 호출을 하나의 트랜잭션에 묶이도록 하는 것을 말합니다.

 

전파 방식 예시

[Transaction]
public void TransferMoney(string fromAccount, string toAccount, decimal amount)
{
    WithdrawMoney(fromAccount, amount);  // 같은 트랜잭션에 포함
    DepositMoney(toAccount, amount);     // 같은 트랜잭션에 포함
}

[Transaction]
public void WithdrawMoney(string account, decimal amount) { ... }

[Transaction] 
public void DepositMoney(string account, decimal amount) { ... }
 
 

 

ACID 특성

트랜잭션의 특징은 원자성, 일관성, 격리성, 지속성이 있으며 이를 ACID 특성이라고 합니다.

 

A - 원자성 (Atomicity)

트랜잭션과 관련된 일이 모두 수행되었거나 되지 않았거나를 보장하는 특징입니다.

예시: 계좌 이체
- 출금과 입금이 모두 성공 → 트랜잭션 커밋
- 둘 중 하나라도 실패 → 전체 롤백

ALL or NOTHING 원칙
 
 

C - 일관성 (Consistency)

허용된 방식으로만 데이터를 변경해야 하는 것을 의미합니다. 데이터베이스에 기록된 모든 데이터는 여러 가지 조건, 규칙에 따라 유효함을 가져야 합니다.

-- 제약 조건 예시
ALTER TABLE accounts ADD CONSTRAINT check_balance CHECK (balance >= 0);

-- 일관성 위반 시 트랜잭션 실패
UPDATE accounts SET balance = -1000 WHERE account_id = 'A';  -- 실패
 
 
 

I - 격리성 (Isolation)

트랜잭션 수행 시 서로 끼어들지 못하는 것을 말합니다. 복수의 병렬 트랜잭션은 서로 격리되어 마치 순차적으로 실행되는 것처럼 작동되어야 합니다.

동시 실행되는 트랜잭션들:
Transaction A: 계좌 A → B 이체
Transaction B: 계좌 B → C 이체

격리성 보장: 서로 간섭 없이 독립적으로 실행
 
 

D - 지속성 (Durability)

성공적으로 수행된 트랜잭션은 영원히 반영되어야 하는 것을 의미합니다. 데이터베이스에 시스템 장애가 발생해도 원래 상태로 복구하는 회복 기능이 있어야 합니다.

지속성 보장 메커니즘

  • 체크섬: 데이터 무결성 검증
  • 저널링: 변경 사항 기록
  • 롤백: 장애 시 복구

무결성 (Integrity)

 

데이터의 정확성, 일관성, 유효성을 유지하는 것을 말하며, 무결성이 유지되어야 데이터베이스에 저장된 데이터 값과 현실 세계의 실제 값이 일치한다는 신뢰가 생깁니다.

 

무결성의 종류

 

1. 개체 무결성 (Entity Integrity)

기본키로 선택된 필드는 빈 값을 허용하지 않습니다.

CREATE TABLE customers (
    customer_id INT PRIMARY KEY,  -- NULL 불가, 중복 불가
    customer_name VARCHAR(50)
);
 
 
 

2. 참조 무결성 (Referential Integrity)

서로 참조 관계에 있는 두 테이블의 데이터는 항상 일관된 값을 유지해야 합니다.

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

-- 존재하지 않는 customer_id로 주문 생성 시 오류 발생
 
 

3. 고유 무결성 (Unique Integrity)

특정 속성에 대해 고유한 값을 가지도록 조건이 주어진 경우, 그 속성 값은 모두 고유한 값을 가집니다.

CREATE TABLE users (
    user_id INT PRIMARY KEY,
    email VARCHAR(100) UNIQUE,  -- 중복 불가
    username VARCHAR(50) UNIQUE -- 중복 불가
);
 
 
 

4. NULL 무결성 (Domain Integrity)

특정 속성 값에 NULL이 올 수 없다는 조건이 주어진 경우, 그 속성 값은 NULL이 될 수 없다는 제약 조건입니다.

CREATE TABLE products (
    product_id INT PRIMARY KEY,
    product_name VARCHAR(100) NOT NULL,  -- NULL 불가
    price DECIMAL(10,2) NOT NULL         -- NULL 불가
);
 
 

격리 수준 (Isolation Level)

 

트랜잭션의 격리성을 구현하는 여러 단계가 있습니다:

격리 수준 Dirty Read Non-Repeatable ReadPhantom Read
READ UNCOMMITTED 발생 발생 발생
READ COMMITTED 방지 발생 발생
REPEATABLE READ 방지 방지 발생
SERIALIZABLE 방지 방지 방지

 

트레이드오프

  • 격리 수준 높음: 데이터 일관성 ↑, 동시성 ↓
  • 격리 수준 낮음: 동시성 ↑, 데이터 일관성 ↓