티스토리 뷰

1. 개요

 이번에 트랜잭션에 대해 배웠다. 그래서 관련된 주요 키워드(ACID, Isolation Level, Savepoint, Lock 등)를 정리하고, 예제 코드를 같이 정리해보려고 한다.

 

2. 트랜잭션(Transaction)

 트랜잭션이란 데이터베이스에서 하나의 작업 단위를 의미한다. 모든 작업이 성공해야만 영구 반영하고, 하나라도 실패하면 전부 되돌릴 수 있게 만들어주는 기능이다. 간단히 요약하자면 All or nothing.

 

3. ACID 특성

 ACID는 트랜잭션이 갖추어야 하는 4가지 필수 특성으로 Atomicity(원자성), Consistency(일관성), Isolation(고립성), Durability(지속성)이 있다.

  • Atomicity (원자성): 모두 수행되거나 전부 안 되거나 (All or nothing)
  • Consistency (일관성): 무결성 제약 등을 항상 만족하도록 보장
  • Isolation (고립성): 트랜잭션의 중간 상태는 다른 트랜잭션에서 볼 수 없음
  • Durability (지속성): COMMIT된 내용은 시스템이 꺼져도 유지됨

 

4. Savepoint

 트랜잭션 중간에 설정할 수 있는 부분 롤백 지점으로, ROLLBACK TO savepoint_name; 으로 돌아갈 수 있다.

 

5. Isolation Leve (격리 수준)

 트랜잭션이 외부 데이터 변경을 얼마나 볼 수 있는지를 제어하는 수준을 의미한다.

수준 설명 허용되는 현상
READ UNCOMMITTED 다른 트랜잭션의 COMMIT 전 변경사항도 읽을 수 있음 Dirty read 허용
READ COMMITTED (기본) COMMIT된 데이터만 읽기 가능 Non-repeatable read 가능
REPEATABLE READ 트랜잭션 내에서 읽은 데이터는 항상 동일 Phantom read 가능
SERIALIZABLE 모든 트랜잭션을 순차적으로 실행한 것처럼 동작 모든 이상 현상 방지

 

5-1. 트랜잭션 이상 현상

  • Dirty Read: 커밋되지 않은 데이터를 읽음
  • Non-repeatable Read: 같은 SELECT가 다르게 보임
  • Phantom Read: WHERE 조건이 같은 SELECT인데 행 개수가 바뀜
  • Serialization Anomaly: 논리적으로 순서가 뒤섞여 잘못된 상태 도달 가능

 

6. Lock

 Lock은 여러 트랜잭션이 동시에 같은 데이터에 접근할 때, 충돌이나 데이터 손상을 막기 위해 설정하는 보호 장치로, 다른 트랜잭션은 잠금이 풀릴 때까지 기다리거나 접근을 막는다.

 

6-1. PostgreSQL에서의 Lock 종류 (중요한 것만)

  • Row-level Lock: 특정 행(row)에 잠금을 걸어 다른 트랜잭션의 수정/삭제를 막음
  • Table-level Lock: 테이블 전체에 대한 읽기/쓰기 제한
  • Advisory Lock: 사용자가 직접 설정하고 해제하는 잠금 (명시적 락)

 

6-2. Lock의 종류

Lock 유형 설명 사용 예
Exclusive Lock 다른 트랜잭션이 읽거나 수정 못 함 SELECT ... FOR UPDATE
Shared Lock 여러 트랜잭션이 읽을 수는 있지만, 수정은 못 함 SELECT ... FOR SHARE

 

6-3. Lock과 Isoltation Level의 관계

  • 격리 수준이 높을 수록 락을 더 많이/오래 걸어서 안전성은 높지만 성능은 떨어짐
  • 낮은 격리 수준에서는 락을 적게 걸고 성능은 높지만, 상술한 이상 현상이 생길 수 있음

 

6-4. PostgreSQL은 기본적으로 어떤 Lock을 어떻게 거는지

작업 락 종류 영향
UPDATE Row-level exclusive lock 해당 행 수정 시 다른 트랜잭션 대기
SELECT FOR UPDATE Row-level exclusive lock 읽으면서 잠금
DELETE Row-level exclusvie lock 삭제할 행에 잠금
SELECT 아무 락 안 걸림 (단, 격리 수준에 따라 내부적으로 제어됨)  

 

7. PostgreSQL의 Auto Commit 모드

 PostgreSQL은 기본적으로 Auto Commit 모드이다. 즉, SELECT/UPDATE/DELETE와 같은 명령어는 그 자체로 하나의 트랜잭션으로 간주되고 자동으로 COMMIT된다. 하지만, 명시적으로 BEGIN ~ COMMIT 또는 ROLLBACK 블록을 사용하면 수동 제어가 가능하다.

 

8. 예시 코드

8-1. 트랜잭션 실행 + Savepoint + Rollback

CREATE TABLE accounts (
  account_id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  account_holder VARCHAR(100) NOT NULL,
  balance DECIMAL(10, 2) NOT NULL CHECK (balance >= 0)
);

INSERT INTO accounts (account_holder, balance) VALUES
('nico', 1000.00),
('lynn', 2000.00);

BEGIN; -- 트랜잭션 시작

-- 1. 린의 잔액을 1500원 추가
UPDATE accounts 
SET balance = balance + 1500 
WHERE account_holder = 'lynn';

-- 2. SAVEPOINT 설정 (중간 되돌림 지점)
SAVEPOINT transfer_one;

-- 3. 실수로 이름을 'rich'로 바꾸는 쿼리 실행
UPDATE accounts 
SET account_holder = 'rich'
WHERE account_holder = 'lynn';

-- 4. 실수를 되돌림
ROLLBACK TO SAVEPOINT transfer_one;

-- 5. nico의 잔액에서 1500원 차감
UPDATE accounts 
SET balance = balance - 1500 
WHERE account_holder = 'nico';

ROLLBACK; -- 전체 작업 취소 (모든 변경사항 되돌림)

COMMIT; -- 의미 없음 (ROLLBACK 했기 때문)

 

8-2. Lock과 FOR UPDATE

BEGIN;

SELECT balance
FROM accounts
WHERE account_holder = 'lynn'
FOR UPDATE;

COMMIT;

 


참고 문서

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/06   »
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 26 27 28
29 30
글 보관함