C.W.K.
Stream
Lesson 08 of 10 · published

ACID, 평범한 말로

~14 min · foundations, transactions

Level 0스키마 새싹
0 XP0/86 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

ATM 이체

ATM 에서 checking 에서 savings 로 $500 옮겨. 기계가 checking 에서 차감. 그 순간 정전. ACID 없으면 $500 이 반쯤 적용된 트랜잭션에 사라져 — 한 계좌에서 빠지고, 다른 계좌엔 안 들어옴. ACID 가 그게 일어날 수 없다는 네 글자짜리 약속이야.

Atomicity — 전부 아니면 전무

트랜잭션은 나눌 수 없는 한 단위. 어느 단계든 실패하면 모든 단계가 시작 안 한 것처럼 롤백. ATM 의 일은 'checking 차감' 이랑 'savings 추가' 를 BEGIN ... COMMIT 안에 감싸는 거. 나머지는 PostgreSQL 이 보장.

Consistency — 룰은 항상 유지

제약 (NOT NULL, CHECK, FK, unique 인덱스) 이 매 commit 에서 강제. 어떤 트랜잭션도 정의된 룰 어기는 상태로 DB 를 두지 못 함. '잔액 ≥ 0' CHECK 있으면 어떤 트랜잭션도 그걸 못 빠져나가.

Isolation — 동시 트랜잭션이 서로 간섭 안 함

두 트랜잭션이 동시에 돌아도 차례로 돌은 것처럼 동작. PostgreSQL 은 MVCC (multi-version concurrency control) 로 — reader 가 writer 안 막고, writer 가 reader 안 막고, 각 트랜잭션이 일관된 스냅샷을 봄.

Durability — commit = 영원히 저장

COMMIT 이 돌아오면 데이터는 디스크에 있음. PostgreSQL 의 WAL (write-ahead log) 가 COMMIT ack 전에 flush. 1ms 후 서버 크래시 나도 recovery 가 WAL 재생, commit 한 데이터 무사.

Code

Atomic 이체·sql
BEGIN;
UPDATE accounts SET balance = balance - 500 WHERE id = 1;
UPDATE accounts SET balance = balance + 500 WHERE id = 2;
COMMIT;
-- 둘 다 바뀌거나, 아무것도 안 바뀜. 부분 상태 없음.
제약이 consistency 보호·sql
ALTER TABLE accounts
ADD CONSTRAINT positive_balance CHECK (balance >= 0);

-- 이제 overdraw 되는 이체는 COMMIT 에서 거절:
BEGIN;
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;  -- balance = -500
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
COMMIT;
-- ERROR: new row violates check constraint "positive_balance"
Isolation 이 동시 read 를 sane 하게·sql
-- Session A                          | -- Session B
BEGIN;                                | BEGIN;
SELECT SUM(balance) FROM accounts;    | UPDATE accounts SET balance = balance + 100
                                      |   WHERE id = 7;
                                      | COMMIT;
SELECT SUM(balance) FROM accounts;    |
-- A 는 같은 합계 두 번 봄, B 가 중간에 commit 했어도.
-- MVCC 가 각 트랜잭션에 일관된 스냅샷 줘.
COMMIT;

External links

Exercise

psql 에서 같은 DB 에 두 connection 열어. 세션 A 에서 BEGIN + 한 행 UPDATE. 세션 B 에서 같은 행 SELECT + UPDATE 시도. 뭐가 막히고 뭐가 안 막히는지, A 에서 COMMIT vs ROLLBACK 시 뭐가 일어나는지 관찰.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.