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

웹 앱의 트랜잭션 패턴

~14 min · transactions, patterns

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

트랜잭션 = 정합성 단위, 속도 단위 아님

모든 HTTP 요청이 보통 DB 작업을 한 트랜잭션에 감쌈. 트랜잭션의 일은 "이거 다 같이 land 또는 안 함" — 성능 feature 아님. Long-running 트랜잭션이 lock 잡고, dead tuple 누적, VACUUM 막고, 모두에게 contention 만듦.

대부분 프로덕션 DB 화재 막는 5 룰

  1. 트랜잭션 짧게. 가능한 늦게 열고, 가능한 빨리 commit. 열린 트랜잭션 안에서 외부 HTTP 호출 안 함.
  2. 유저 입력 가로질러 트랜잭션 잡지 마. BEGIN, 유저가 폼 채우길 기다림, COMMIT — 분 단위 row lock 잡음.
  3. 이유 없으면 READ COMMITTED. 좋은 이유 있어 default.
  4. REPEATABLE READ 또는 SERIALIZABLE 쓰면 항상 SerializationFailure 처리. Backoff 와 retry.
  5. 여러 라운드트립 가로질러 SELECT FOR UPDATE 회피. Lock-then-think-then-update 해야 하면 stored procedure 한 개 또는 statement 한 개에.

웹 요청 트랜잭션 템플릿

모든 프레임워크가 요청을 트랜잭션에 감싸는 깨끗한 방법 가짐. 사용. Route handler 의 커스텀 BEGIN/COMMIT 이 트랜잭션 누수 일어나는 방법.

Code

FastAPI + SQLAlchemy 템플릿·python
from fastapi import Depends
from sqlalchemy.orm import Session

def get_db():
    db = SessionLocal()
    try:
        yield db
        db.commit()
    except Exception:
        db.rollback()
        raise
    finally:
        db.close()

@app.post("/orders")
def create_order(payload: OrderIn, db: Session = Depends(get_db)):
    order = Order(...)
    db.add(order)
    db.flush()  # 자동 생성된 id
    for item in payload.items:
        db.add(OrderItem(order_id=order.id, ...))
    return order
이거 하지 마·python
# 외부 HTTP 호출 가로질러 트랜잭션 잡음 — deadlock 시한폭탄
def risky(db):
    with db.transaction():
        order = db.execute("INSERT INTO orders ... RETURNING id").fetchone()
        # ❌ 열린 트랜잭션 안 외부 API 호출
        ext = httpx.post("https://payments.example.com/charge", json={...})
        db.execute("UPDATE orders SET payment_id = %s WHERE id = %s",
                   (ext.json()["id"], order["id"]))

External links

Exercise

프로젝트의 한 route 감사: 트랜잭션이 어디 시작, 언제 commit, 안에 뭐 실행. 외부 네트워크 호출이 트랜잭션 윈도우 안에 살면 안 그렇게 재설계.

Progress

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

댓글 0

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

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