한양과학기술고등학교

에듀테크 프로젝트 대시보드

트랜잭션

BEGIN COMMIT ROLLBACK SAVEPOINT idle in transaction

여러 문장을 전부 성공 아니면 전부 취소로 묶습니다. PostgreSQL 은 DDL 도 트랜잭션 안에서 롤백됩니다.

1. 기본

BEGIN;
  UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
  UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
COMMIT;      -- 둘 다 반영. 중간에 에러/ROLLBACK 이면 둘 다 취소

psql·대부분 드라이버는 기본 autocommit — 문장 하나하나가 암묵적 트랜잭션입니다. BEGIN 을 해야 묶입니다.

2. SAVEPOINT — 부분 롤백

BEGIN;
  INSERT INTO orders ...;
  SAVEPOINT sp1;
  INSERT INTO order_items ...;   -- 실패 가능
  -- 에러 시:
  ROLLBACK TO SAVEPOINT sp1;     -- 여기까지만 취소, 트랜잭션은 유지
  INSERT INTO order_items ... ;  -- 다시 시도
COMMIT;
주의
  • 트랜잭션 중 에러가 하나라도 나면 그 이후 모든 문장이 current transaction is aborted 로 거부됨 — ROLLBACK 하거나 SAVEPOINT 로 복구해야 함

3. DDL 트랜잭션

BEGIN;
  ALTER TABLE users ADD COLUMN nickname text;
  CREATE INDEX idx_users_nick ON users (nickname);
  -- 문제가 있으면
ROLLBACK;    -- 스키마 변경이 전부 사라짐 (MySQL 과 크게 다른 점)

예외: CREATE INDEX CONCURRENTLY, CREATE DATABASE, VACUUM 등은 트랜잭션 블록 안에서 불가.

4. idle in transaction 위험

열어놓고 방치하면
  • 잡은 락이 안 풀리고, VACUUM 이 그 시점 이후 죽은 행을 못 치움(bloat)
  • 방어: idle_in_transaction_session_timeout = '30s', 앱에서 트랜잭션을 짧게
SELECT pid, state, now() - xact_start AS 지속
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY xact_start;
"인덱스는 공짜가 아니다 — 읽기를 빠르게 하고 쓰기를 느리게 한다"