티스토리 뷰
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;
참고 문서
'기록' 카테고리의 다른 글
PostgreSQL의 확장 기능 (Extensions) 중 hstore, pgcrypto, uuid-ossp에 대해 정리 (0) | 2025.04.20 |
---|---|
PostgreSQL의 JSON/JSONB 배운 것 정리 (0) | 2025.04.19 |
PostgreSQL Function & Procedure 배운 것 정리 (0) | 2025.04.13 |
PostgreSQL에서 문자열 기반 다대다 관계 정규화하기 — 영화 장르 예제 (0) | 2025.04.12 |
MySQL Full-Text Search (0) | 2025.04.12 |
- Total
- Today
- Yesterday
- 리액트
- typescript
- Redux
- 브루트포스
- 구현
- async
- 비트마스킹
- 동적계획법
- 넥스트js
- 백준
- BFS
- 다이나믹프로그래밍
- 자바스크립트
- SQL
- 순열
- 알고리즘
- NextJS
- 스택
- CSS
- 완전탐색
- 카카오맵
- 햄버거버튼
- aws
- C++
- react
- 프로그래머스
- Next.js
- themoviedb
- 타입스크립트
- 코드스테이츠
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |