Serializable

Serializable 은 트랜잭션 동시성에서 가장 강한 격리 수준으로, 실행 결과가 어떤 순차적 실행과 같도록 보장해 Dirty Read·Non-Repeatable Read·Phantom 등 모든 이상현상을 차단한다.
구현 방식은 잠금 (Strict 2PL), MVCC 기반의 직렬성 검증 (SSI), 또는 낙관적 검증 (OCC) 등이며, 분산 환경에서는 2PC·분산 합의·외부 시계 같은 추가 메커니즘이 필요하다.
실무에서는 데이터 무결성이 절대적일 때 우선 적용하되 성능 저하·교착·재시도 비용을 인덱스 튜닝, 트랜잭션 단축, 백오프/재시도 설계, 부분적 격리 상향 (핵심 경로만) 으로 완화하는 것이 핵심 전략이다.

핵심 개념

직렬가능성 (Serializable) 은 여러 트랜잭션이 동시에 실행돼도 그 결과가 어떤 순서로 하나씩 처리한 것과 정확히 같도록 보장하는 격리 수준이다. 데이터 무결성을 최대로 보장하기 때문에 금융·결제 같은 핵심 업무에서 쓰인다. 구현은 전통적 락 (Strict-2PL) 이나 최신 MVCC 기반의 SSI 같은 방식이 있는데, 모두 교착·성능 저하라는 비용을 동반하므로 실제 적용은 핵심 트랜잭션으로 제한하고, 애플리케이션은 재시도와 모니터링을 준비해야 한다.

핵심 개념 (한글,약어)정의 (요약)왜 중요한가 (실무 관점)
직렬가능성 (Serializable)동시 실행 결과가 어떤 직렬 스케줄과 동일한 성질데이터 일관성 최상 필요 시 필수
충돌 직렬가능성 (Conflict-Serializability)충돌 그래프에 사이클이 없으면 성립스케줄 분석·모니터링용 판정 기준
2 단계 잠금 (2PL) / 엄격 2PL(S-2PL)락 획득/해제 규칙으로 직렬성 보장단순·직관적, 락 경쟁·교착 유발
다중버전 동시성 제어 (MVCC)읽기용 스냅샷으로 블로킹 최소화읽기 성능 개선, 장기 트랜잭션 비용 존재
Serializable Snapshot Isolation(SSI)MVCC 위에서 의존성 탐지로 직렬성 보장MVCC 장점 유지 + 직렬성, abort 가능성
팬텀 (Phantom)범위 질의에서 새로운 행이 보이는 현상집계/범위 제약 정확성에 영향
쓰기 스큐 (Write Skew)상호 의존 규칙을 우회하는 동시 갱신비즈니스 무결성 위험
2 단계 커밋 (2PC)분산 트랜잭션의 커밋 합의 프로토콜분산 환경에서 원자성 보장하지만 비용 큼
TrueTime / 글로벌 타임스탬프전역 시간 동기화 메커니즘분산 직렬성 (Spanner 스타일) 구현 기반

Serializable 관련 개념들은 서로 보완·대체 관계에 있다. 전통적 2PL 은 즉시적 직렬성 보장에 간단하지만 락 비용이 크고, MVCC 는 읽기 성능을 살리되 직렬성 보장을 위해 SSI 같은 추가 기법이 필요하다. 실무에서는 비즈니스 요구에 따라 적절한 조합을 선택하고, 애플리케이션 쪽에서 재시도·일관성 검증을 준비해야 한다.

개념 간 상호관계

출발 개념 → 도착 개념관계 (방향성)무엇을 위해 / 어떤 영향
Serializable → 2PL / S-2PL구현 관계 (직렬성 보장 수단)락으로 충돌 해결 → 직렬성 보장, 블로킹 증가
MVCC → SSI확장 관계 (직렬성 보장 보완)MVCC 에 의존성 탐지 추가 → 직렬성 보장, abort 발생
2PL → Deadlock원인 관계락 획득 순서·경합 → 데드락 발생 가능성
SSI → Abort/Retry결과 관계충돌 탐지 시 트랜잭션 강제 종료 → 재시도 필요
Phantom → Predicate Locking / Next-Key Lock완화 수단 관계팬텀 방지 위해 범위 잠금 적용
2PC → 분산 Serializable조합 관계분산 트랜잭션의 전역 직렬성 보장 (비용↑)

관계는 대부분 " 무엇으로 직렬성을 실현하느냐 (구현 수단)" 와 " 어떤 부작용이 파생되느냐 (데드락/abort)" 로 요약된다. 방향성을 보면 구현 (예: MVCC→SSI) 은 성능 향상과 보장 간 트레이드오프로 이어지고, 락 기반 (2PL) 은 단순하지만 블로킹을 낳는다. 실무적 선택은 이 흐름을 이해하고 해당 워크로드에 맞춰 조정해야 한다.

개념별 실무 연관성

핵심 개념 (한글,약어)실무에선 무엇을 하게 되는가 (무엇)어떻게 적용되는가 (방법)왜 필요한가 (이유)
직렬가능성 (Serializable)핵심 트랜잭션에 적용DB 격리 설정 또는 SSI/2PL 사용, 재시도 로직 준비무결성 보장 (금융·정산)
MVCC읽기 성능 확보버전 스토어 유지, VACUUM/GC 튜닝대량 읽기·비동기 분석 성능
2PL / S-2PL강력한 충돌 차단락 정책·타임아웃·데드락 탐지단순 명확한 직렬성 보장
SSIMVCC 에서 직렬성 보장의존성 탐지·충돌 시 abortMVCC 의 이점 유지하며 직렬성 확보
2PC분산 커밋 안전화조정자/참여자 프로토콜, 리커버리 로직분산 트랜잭션의 원자성 확보
재시도/Idempotency충돌 시 안정 복구애플리케이션 레벨 재시도·중복허용 처리abort 발생 시 서비스 안정성
Predicate/Next-key Lock팬텀 방지범위 잠금 적용, 인덱스 적절화범위 질의 무결성 보장

실무에서는 단순히 DB 옵션만 바꾸는 게 아니라 애플리케이션 (재시도·idempotency), 운영 (모니터링·GC 튜닝), 설계 (인덱스·쿼리 구조) 전부를 함께 바꿔야 직렬가능성을 안정적으로 도입할 수 있다. 분산 상황에서는 2PC/글로벌 타임스탬프 같은 추가적 비용을 감수해야 한다.

기초 조사 및 개념 정립

Serializable 의 본질과 운영지침

Serializable 은 데이터베이스의 가장 강한 격리 수준으로, 여러 트랜잭션이 동시에 실행되더라도 마치 어떤 순서로 하나씩 실행된 것처럼 결과가 동일하게 보이도록 보장한다.
이로 인해 더티리드 (DIRTY), 비반복 읽기 (NON-REPEATABLE), 팬텀 리드 (PHANTOM) 같은 모든 동시성 문제를 예방한다.
구현은 전통적인 엄격 2 단계 잠금 (Strict 2PL) 으로 행·범위 락을 유지하거나, MVCC 기반의 직렬성 (예: SSI) 을 통해 충돌을 감지하고 재시도함으로써 달성한다.
장점은 완전한 일관성이며, 단점은 성능·동시성 (throughput) 손실과 데드락/재시도 증가다. 따라서 핵심 금융·결산 등 높은 정확성이 요구되는 워크로드에서 우선 적용하되, 적용 전 벤치마크·재현 테스트·재시도 정책을 반드시 설계해야 한다.

  • 정의 (요약): Serializable 은 모든 동시 실행 트랜잭션의 외형적 결과가 어떤 일련의 단일 - 스레드 (직렬) 실행 결과와 같도록 보장하는 격리 수준이다.

  • 근본 메커니즘:

    • 락 기반 (Strict 2PL): 트랜잭션이 읽거나 쓴 자원에 대해 적절한 락을 취득하고, 커밋/롤백까지 락을 해제하지 않아 다른 트랜잭션의 간섭을 물리적으로 차단한다. 이 방식은 팬텀·비반복·더티 모두 차단하지만 데드락과 대기 비용이 크다.
    • 스냅샷 기반 (SSI 등): 트랜잭션마다 스냅샷을 부여해 읽기는 무블로킹으로 수행하고, 커밋 시점에 충돌 (직렬화 이상) 을 감지하면 일부 트랜잭션을 abort(재시도) 시켜 직렬성 보장한다. 읽기 성능은 우수하지만 재시도 확률이 증가할 수 있다.
  • 실무적 본질적 고려: 직렬성 도입은 ’ 정합성 확보 ’ 라는 명확한 목적을 달성하지만, 동시성·응답성·확장성에 대한 비용과 운영 복잡도가 따라온다. 설계 단계에서 어떤 트랜잭션이 절대적 일관성을 요구하는지를 정의하고, 그 범위만 직렬화하거나 하이브리드 패턴 (선택적 상향, 리플리카 분리, SSI 활용) 을 적용하는 것이 실무 핵심이다.

Serializable: 등장배경·기술 발전사

데이터베이스의 최고 격리인 Serializable은 여러 트랜잭션을 마치 순서대로 하나씩 실행한 것과 동일한 결과를 보장하 위한 개념이다.
초기에는 락 기반 (2PL) 으로 직렬성을 확보했지만, 읽기 위주의 워크로드에서 성능이 급격히 떨어졌다.
그래서 MVCC 가 등장해 읽기 성능을 살렸고, MVCC 의 한계를 보완하기 위해 gap-lock 같은 락 전략이나 충돌탐지 기반의 SSI 가 개발되어 **정합성 (Serializable 에 근접한 보장)**과 성능 (읽기 비차단) 사이의 균형을 찾아왔다.
규제·회계 등 엄격한 일관성이 필요한 시스템에서는 여전히 Serializable(또는 그에 준하는 기법) 을 선택한다.

등장 배경
  • 트랜잭션 동시성으로 인한 데이터 불일치 (예: Lost Update, Dirty Read, Non-repeatable, Phantom) 가 실무에서 큰 문제를 만들었고, 이를 이론적으로 해결하려는 시도 (직렬화 가능성 연구) 가 1970 년대 이후 활발해졌다.

  • 산업 현장에서는 " 정확성 보장 " 요구 (금융·회계 등) 와 " 높은 동시성/낮은 지연 " 요구 (웹·분석 서비스) 가 충돌했고, 이 둘을 조화시키려는 여러 기술이 등장했다.

발전 과정
발전 단계핵심 기술/개념대표 문제 해결점한계·부작용
락 기반 (2PL)S/X 락, 트랜잭션 직렬화데이터 무결성 보장읽기 성능 저하, 데드락
MVCC버전 체인, 스냅샷 가시성읽기 비차단, 높은 처리량옛 버전 보존 비용, 팬텀 완전 차단 어려움
Gap/Next-key Lock범위 락 (갭 락)팬텀 제어 (범위 삽입 차단)락 오버헤드 증가
SSI (충돌탐지)MVCC + 런타임 충돌 검출MVCC 유지하면서 직렬화 보장 개선충돌 시 재시도 비용
Serializable (고급)엄격 직렬성 스케줄링/검증최고 수준 일관성성능·운영 복잡도 증가
timeline
    title Serializable 관련 기술 발전 타임라인 (개괄)
    1970s : 직렬화 가능성 이론 발전 (학계)
    1980s : 락 기반 2PL 상용 DB 채택
    1990s : MVCC 채택 확산 (읽기 비차단 목표)
    2000s : gap/next-key lock 등 혼합 전략 채택 (팬텀 제어)
    2010s : SSI(충돌탐지) 등의 고급 MVCC 보완 기법 등장
    2010s+ : 엔진별 Serializable 옵션·정교화
  • 핵심 흐름: 정확성 확보 (락 기반) → 성능 요구로 MVCC 등장 → MVCC 의 팬텀·쓰기왜곡 약점 보완 (갭 락, SSI 등) → 필요시 최고 격리 (Serializable) 선택.

  • 의미: 각 단계는 " 어떤 문제를 해결하려 했는가 " 와 " 그 해결이 초래한 새 문제 (부작용)" 를 함께 갖는다. 따라서 설계자는 비즈니스 요구 (정합성 민감도, 지연 허용치) 에 따라 적절한 지점을 선택해야 한다.

Serializable: 문제·목표·실무가이드

Serializable 은 데이터베이스에서 가장 엄격한 격리 수준이다. 여러 트랜잭션이 동시에 수행되더라도, 결과는 어떤 순서로 하나씩 실행했을 때 (직렬화) 와 똑같이 나온다. 그래서 회계·금융처럼 결과의 완전성과 불변성이 절대적으로 중요한 영역에서 사용된다. 구현은 락을 길게 유지하거나 (Monolithic 2PL), 최신 DB 의 경우 MVCC 기반으로 충돌을 감지해 잘못된 실행을 취소시키는 방식 (SSI) 을 사용한다. 강한 안전성을 제공하지만 성능·복잡도 비용이 크므로 필요한 곳에만 제한적으로 적용한다.

Serializable 이 해결하는 문제들
해결 문제문제의 본질Serializable 이 해결하는 방식실무적 이득
동시성으로 인한 비결정성동시 실행 순서에 따라 최종 상태가 달라짐직렬화 보장 (락/충돌감지) → 어떤 순서로 실행하더라도 동일 결과결과 예측성·디버깅 용이
Non-repeatable Read / Dirty Read재조회 시 값 변하거나 미커밋 값 노출모든 이상현상 차단 (직렬화로 귀결)계산·정산 오류 방지
Phantom (범위 삽입)같은 조건의 재조회에서 행 집합 변화범위 락 또는 충돌감지로 새 행 노출 방지범위 기반 집계 안정성 확보
응용 불변식 위반복합 비즈니스 규칙이 동시성으로 깨짐트랜잭션 수준에서 불변식 보장보정·사후검사 비용 절감

Serializable 은 동시성으로 인해 발생하는 모든 일관성 이상 (읽기 불일치, 팬텀 등) 을 데이터베이스 수준에서 제거함으로써, 응용 레벨의 비즈니스 불변식까지 강력하게 보호한다. 다만 이를 위해 락 유지 또는 충돌 감지와 같은 비용을 지불해야 하므로, 도입 전 성능 영향과 재시도·블로킹 시나리오를 검증해야 한다.

Serializable 의 핵심 목적
핵심 목적구체 설명기대되는 효과
직렬성 보장 (Serializability)동시 실행의 결과가 어떤 직렬 실행과 동일하게 유지되도록 보장예측 가능한 시스템 상태, 규정 준수 용이
비즈니스 불변식 보호DB 제약을 넘는 응용 규칙 (합계 보존 등) 도 트랜잭션 수준에서 보장보정·감사 비용 절감
데이터 신뢰성 극대화모든 이상현상 (Dirty/Non-repeatable/Phantom) 제거운영 신뢰성·감사 추적성 향상

핵심 목적은 _ 시스템 전체의 결정론적 일관성 유지 _ 이며, 이는 금융·회계 등 엄격한 신뢰성 요구 분야에서 직접적인 비즈니스 가치를 제공한다. 목적 달성을 위해서는 성능과 재시도 전략을 포함한 운영 설계가 필요하다.

문제와 목적의 연결 맵
해결 문제연관 핵심 목적어떻게 연결되는가
동시성 비결정성 제거직렬성 보장직렬화 보장 메커니즘이 문제를 직접 해소
Non-repeatable/Dirty Read 제거데이터 신뢰성 극대화이상현상 제거 → 신뢰성 확보
Phantom 억제비즈니스 불변식 보호범위 안정성으로 범위 기반 규칙 보장
응용 불변식 위반 방지비즈니스 불변식 보호 / 직렬성트랜잭션 단위 보장이 불변식 유지로 이어짐

각 문제는 Serializable 의 특정 목적과 직접적으로 연결된다. 예컨대 팬텀 문제는 범위 안정성을 제공하는 직렬성 보장 메커니즘을 통해 해결되며, 그러므로 문제 - 목적 매핑을 통해 어떤 메커니즘이 필요한지 설계 단계에서 바로 판단할 수 있다.

Serializable 적용 전제와 운영 요건

Serializable 을 안전하게 운영하려면 트랜잭션 경계를 명확히 하고 트랜잭션을 짧게 설계해야 한다.
인덱스를 적절히 구성해 불필요한 범위 스캔을 줄이고, 락 (또는 검증) 기반으로 직렬성 보장을 구현해야 한다.
락 경쟁·데드락·언두 증가 등 성능 이슈를 모니터링하고, 충돌 발생 시 안전하게 재시도할 수 있는 멱등성·보상 로직을 준비해야 한다.
이러한 조건을 만족하는 시스템에서만 Serializable 적용을 권장한다.

Serializable 전제·요구 체크리스트
전제/요구사항설명근거 (무슨 문제로부터 기인)실무 영향권장 조치
트랜잭션 경계 명확화트랜잭션 시작/종료 규칙 문서화불명확 경계는 긴 tx 유발언두·락 축적, 디버깅 난이도 증가코드·아키텍처 규약 수립
짧은 트랜잭션 설계외부 I/O 분리, 연산 분해긴 tx 는 락 보유시간 증가deadlock·throughput 저하타임아웃 설정, 비동기화
적절한 인덱스쿼리 커버링·범위 최소화범위 스캔 → gap/next-key 락 확대락 확산·성능 저하인덱스 리펙토링, 쿼리 튜닝
락/검증 메커니즘Strict 2PL 또는 SSI 등 구현직렬성 보장 필요성충돌/재시도·대기 증가DB 옵션 검토·설정
락 경쟁 관리timeout, deadlock detect, escalation교착/경합으로 가용성 저하장애 및 복구 비용 증가모니터링·자동화·SRE Playbook
멱등성·재시도 설계idempotency token, 보상 트랜잭션충돌로 트랜잭션 abort 발생 가능사용자 영향 완화설계·코드 수준 구현
리소스·성능 검증부하 테스트로 재시도율·throughput 측정직렬화 적용 시 성능 저하 가능SLA 미달 위험사전 성능 테스트
적용 도메인 선정정합성 우선 영역에 적용모든 트랜잭션에 적용하면 과비용운영비 증가핵심 트랜잭션만 선별 적용

Serializable 은 강력한 정합성 보장을 위해 필요한 전제 (짧은 트랜잭션, 인덱스, 락/검증 메커니즘, 멱등성 등) 가 많다. 이 전제들이 충족되지 않으면 성능·가용성 문제로 실무에 큰 부담을 준다. 따라서 핵심 트랜잭션에만 선별 적용하고, 적용 전 DB 별·시나리오별 검증을 통해 임계값을 정의해야 한다.

Serializable 핵심 특징·운영 포인트

Serializable 은 데이터베이스에서 가장 강한 격리 수준으로, 여러 트랜잭션이 동시에 실행되어도 마치 어떤 순서로 하나씩 실행된 것과 같은 결과만 나오도록 보장한다.
이를 위해 시스템은 읽기·쓰기에 대해 강력한 제어 (잠금이나 충돌 검증) 를 적용하고, 분산 환경에서는 합의 프로토콜을 동원한다.
그 결과 데이터 무결성은 극대화되지만 처리량은 줄고 지연·재시도 가능성이 커진다. 실제 운영에서는 성능 비용 때문에 모든 트랜잭션에 적용하기보다, 금전·규제·불변식이 중요한 핵심 경로에만 적용하는 전략을 쓴다.

Serializable 핵심 특징표
핵심 특징기술적 근거다른 기술과의 차별점실무 영향 / 권장 적용
이상현상 완전 차단직렬화 그래프 무사이클 보장 (2PL/SSI/OCC)RC/RR 등은 일부 이상현상 허용금전·규제 경로 우선 적용
읽기도 제어공유락 또는 의존 추적·검증MVCC 낮은 격리는 읽기 비차단SELECT 도 비용 발생
수학적 직렬성 보장스케줄이 직렬 스케줄과 등가약한 격리는 등가성 불완전데이터 무결성 최우선 상황에 유리
성능·지연 비용락 경합·충돌 검증·분산 합의 오버헤드약한 격리보다 처리량 낮음전체 적용 비권장, 부분 적용 권장
재시도/교착 필요성충돌 시 abort/재시도, 데드락 탐지RC/RR 에서는 빈도 낮음idempotency·백오프 설계 필수
  • Serializable 은 정확성 (무결성) 을 극대화하지만 **성능·운영 비용 (재시도, 데드락, 지연)**을 동반한다.
  • 실무는 엔진 특성과 비즈니스 위험을 바탕으로 핵심 경로에 국소 적용하고, 재시도/백오프·idempotency·샤딩·인덱스 설계로 비용을 완화해야 한다.

Phase 2: 핵심 원리 및 이론적 기반

Serializable 설계 원칙·철학 가이드

Serializable 은 " 동시 작업을 아무리 많이 해도, 결과는 어떤 순서로 하나씩 처리한 것과 똑같다 " 는 규칙이다.
금융·정산처럼 정확성이 생명인 곳에서 쓰이며, 대신 성능·동시성이 낮아질 수 있다.
그래서 보통은 모든 트랜잭션에 적용하지 않고, 핵심 작업에만 선택적으로 적용한다.
구현은 락 (전통적) 이나 MVCC+ 충돌탐지 (현대적) 방식이 있고, 애플리케이션은 abort·재시도를 처리하도록 준비해야 한다.

Serializable 핵심 원칙 표
핵심 원칙설명목적 (무엇을 위한)왜 필요한가 (근거)
정확성 우선결과의 정확성을 최우선으로 둠비즈니스 무결성 확보무결성 손실은 금전적·법적 리스크
직렬성 보장동시 실행을 직렬 결과와 동등하게모든 이상현상 제거회계/결제 등 강한 일관성 필요
선택적 적용핵심 트랜잭션에만 적용성능 저하 최소화전체 시스템 성능 보전 필요
복구·재시도 준비충돌 시 안전 재시도 보장사용자 경험·서비스 연속성SSI/2PL 은 abort 발생 가능
관찰성 확보락/abort 등 지표 모니터링문제 조기 탐지·대응운영 문제를 빠르게 파악·완화

핵심 원칙은 ’ 정확성 ’ 을 중심으로 설계·운영하는 가이드라인이다. 실무에서는 직렬성의 이득 (무결성) 과 비용 (성능·운영 복잡성) 을 균형 있게 관리하기 위해 선택적 적용, 재시도 로직, 모니터링을 반드시 병행해야 한다.

Serializable 설계 철학 표
설계 철학설명목적 (무엇을 위한)왜 필요한가 (근거)
정확성 - 우선 아키텍처핵심 영역엔 일관성, 주변엔 성능위험 분리 및 비용 집중전체 성능 저하 없이 핵심 보호
작은 범위·짧은 Tx트랜잭션은 작고 빠르게락·버전 보관 부담을 줄임장기 트랜잭션이 비용 폭증 유발
구현 선택성 (MVCC vs 2PL)워크로드에 맞는 방법 선택최적의 성능·일관성 균형한 방식만으로 모든 상황 대응 불가
애플리케이션 보강DB 외 검증·재검증 도입비즈니스 제약 보완DB 만으로는 모든 규칙 보장 불가
분산 비용 수용 정책글로벌 일관성 적용 가이드라인기대치·SLA 명확화분산 직렬성은 높은 비용 요구

설계 철학은 ’ 어디에 직렬성을 적용할지, 어떤 방식으로 보완할지 ’ 에 대한 큰 그림이다. 핵심은 " 무엇을 위해 일관성이 필요한가 " 를 기준으로 설계 결정을 내리고, 운영·애플리케이션 측면의 보완책을 전제로 삼는 것이다.

Serializable 메커니즘과 충돌처리 흐름

Serializable 은 데이터 일관성을 최우선으로 하는 격리 수준으로, 모든 동시 트랜잭션의 최종 결과가 어떤 순차 실행 순서와 같도록 보장한다.
구현 방식은 크게

  1. 락 기반 (Strict 2PL)—충돌을 물리적으로 차단해 직렬성 확보
  2. MVCC+SSI—읽기는 스냅샷으로 무블로킹 처리하고 커밋 시 충돌을 검출해 재시도하여 직렬성 보장
  3. OCC—커밋 시 검증하는 방식이다.

각 방식은 성능·대기·재시도 특성이 다르므로 실무 적용 전 벤더별 동작과 재시도 정책을 확인해야 한다.

Serializable 메커니즘 비교표
메커니즘동작 요지장점단점실무 적용 포인트
Strict 2PL (락 기반)읽기/쓰기 시 락 획득·커밋까지 유지직렬성 확실·단순데드락·대기·확장성 저하데드락 탐지/타임아웃 필요
MVCC + SSI읽기는 스냅샷, 커밋 시 rw-dep 추적→충돌시 abort읽기 무블로킹·좋은 읽기 성능충돌시 재시도·복잡성serialization failure 재시도 로직
OCC (검증)커밋 전 Validation, 위반시 abort락 오버헤드 없음 (낙관적)충돌 잦으면 비용 급증충돌율 낮은 워크로드 권장

Serializable 보장은 메커니즘에 따라 성능·운영 비용이 크게 달라진다. 락 기반은 강력하지만 확장성이 낮고, MVCC+SSI 는 읽기 성능 우수하나 충돌 발생 시 재시도가 필요하며, OCC 는 충돌 희박 환경에서 효율적이다. 실무 적용 시 워크로드 특성 (읽기/쓰기 비율·충돌율) 을 기준으로 메커니즘을 선택하라.

Serializable 처리 흐름도
flowchart TD
  A[트랜잭션 시작] --> B{동작: Read/Write}
  B -->|Read| C[스냅샷 조회 또는 Shared Lock 요청]
  B -->|Write| D[Write Buffer / X Lock 요청]
  C --> E{메커니즘}
  D --> E
  E -->|2PL| F[락 획득 유지 → 충돌 시 락 대기/데드락 탐지]
  E -->|MVCC+SSI| G[읽기 스냅샷, 커밋 시 rw-dep 기록]
  E -->|OCC| H[로컬 작업 → 커밋 시 Validation]
  F --> I{충돌?}
  G --> J{"충돌(순환)?"}
  H --> K{검증 실패?}
  I -->|예| L[데드락 처리 or 타임아웃 → 재시도/Abort]
  I -->|아니오| M[정상 진행]
  J -->|예| L
  J -->|아니오| M
  K -->|예| L
  K -->|아니오| M
  M --> N[커밋 성공]
  L --> O[트랜잭션 abort → 재시도 정책 적용]

흐름도는 트랜잭션이 읽기/쓰기를 수행할 때 선택되는 메커니즘 (락 기반 / MVCC+SSI / OCC) 에 따라 충돌 처리 방식이 달라지는 것을 보여준다.
락 기반은 자원에 대한 락을 유지해 충돌을 물리적으로 차단하지만 데드락과 대기 발생 가능성이 있다.
MVCC+SSI 는 읽기를 스냅샷으로 처리해 읽기 성능을 확보하고, 커밋 시점에 의존성 그래프를 검사해 순환이 발견되면 일부 트랜잭션을 abort 하여 직렬성을 보장한다.
OCC 는 커밋 전 검증 단계에서 위반을 발견하면 rollback 한다. 실무에서는 재시도·타임아웃·데드락 탐지·모니터링을 함께 설계해야 한다.

Serializable: 제어·데이터 흐름과 생명주기

Serializable 은 여러 트랜잭션이 동시에 일어나도 마치 차례대로 (직렬) 실행된 것처럼 행동하게 하는 격리 목표다. 이를 위해 DB 는 트랜잭션의 읽기/쓰기 관계를 추적하고 (혹은 락을 걸고), 순환 의존이 생기면 일부 트랜잭션을 중단시켜 시스템 전체가 직렬성과 일관성을 유지하도록 한다. 구현 방식 (락 vs MVCC+ 충돌탐지) 에 따라 대기·재시도 등 부작용이 다르므로 운영·설계 시 주의가 필요하다.

Serializable 제어 흐름 상세
동작 흐름 (단계별)
  • Start: 트랜잭션 생성 → ID/시작 TS 할당 (또는 스냅샷).
  • Read:
    • 락: S-lock 획득 → 다른 트랜잭션의 X-lock 충돌로 대기 가능.
    • MVCC: 스냅샷 기준 읽음 → 의존성 (읽음 대상과 트랜잭션) 을 기록.
  • Write:
    • 락: X-lock 획득 → 다른 트랜잭션 대기.
    • MVCC: 새 버전 생성 (undo 정보 유지), write 의존성 그래프에 간선 추가.
  • CC 처리: 의존성 그래프 갱신 → 주기적 또는 이벤트 기반으로 cycle 검사.
  • Resolve: cycle 발견하면 abort(혹은 deadlock victim 선택).
  • Commit: 가시성 규칙에 따라 버전 공개 (또는 log flush) → 후속 트랜잭션이 볼 수 있음.
  • Cleanup: 락 해제/가비지 컬렉션.
Serializable 데이터·제어 흐름 표
단계동작 (요약)CC 영향/반응운영 모니터 항목
시작트랜잭션 생성, TS/ID 할당스냅샷 기준/락 정책 결정txn 시작률, 평균 시작간격
읽기SELECT 처리 (S-lock or snapshot)읽기 의존성 기록 / 잠금 대기 발생 가능read latency, lock waits
쓰기UPDATE/INSERT/DELETE 처리쓰기 의존성 추가, 잠금 획득 or 버전 생성write latency, lock waits
의존성 추적rw/rwr 간선 유지그래프 크기 증가 → 성능영향dependency graph size
충돌 탐지cycle/unsafe pattern 탐지deadlock/serialization failure 발생 → abortdeadlocks, serialization failures
커밋로그 flush, 버전 가시화가시성 전파, 후속 txn 영향commit latency, fsync 시간
정리락 해제, GC 수행리소스 해제, 버전 정리long-running txns, GC backlog

요약하면 데이터·제어 흐름은 연산이 의존성을 만들고 (CC 가 이를 추적), 그 의존성 속에서 오류 (사이클) 가 날 경우 일부 트랜잭션을 중단해 전체 시스템의 직렬성 (Serializable) 을 지키는 과정이다. 운영에서는 특히 의존성 그래프 크기·장기 트랜잭션·deadlock·serialization failures를 중점적으로 모니터링해야 한다.

Serializable: 데이터·제어 흐름도
flowchart LR
  Start[트랜잭션 시작]
  Start --> Read["READ (S-lock or Snapshot)"]
  Read --> Write["WRITE (X-lock or new version)"]
  Read -->|의존성 등록| Dep[의존성 그래프 업데이트]
  Write -->|의존성 등록| Dep
  Dep --> Check[충돌/사이클 검사]
  Check -->|사이클 없음| Proceed[계속 실행]
  Check -->|사이클 탐지| Abort[Abort / Serialization Failure]
  Proceed --> Commit[커밋 -> 가시성]
  Commit --> Cleanup[락 해제 / GC]
  Abort --> Cleanup
  • 트랜잭션이 읽기/쓰기를 수행할 때 CC 가 의존성을 기록한다. 기록된 의존성은 그래프로 관리되며, 일정 기준 (또는 이벤트) 에 따라 cycle detection을 수행한다. cycle 발견 시 DB 는 정책 (데드락 victim, 또는 serialization failure victim) 에 따라 하나 이상의 트랜잭션을 abort 시켜 그래프를 깨고 직렬성을 보장한다. 성공적으로 커밋되면 변경은 가시화되고 후속 트랜잭션이 이를 본다. 이후 락 해제 또는 MVCC 의 경우 가비지 컬렉션으로 오래된 버전을 회수한다.
트랜잭션 생명주기 (Serializable)
sequenceDiagram
  participant C as Client
  participant DB as DB Engine / CC
  C->>DB: BEGIN
  DB-->>C: tx_id / snapshot
  C->>DB: SELECT (read) 
  DB-->>C: rows (from snapshot or lock)
  C->>DB: UPDATE (write)
  DB-->>DB: register dependency, acquire lock / create version
  C->>DB: COMMIT
  DB-->>DB: check conflicts -> commit success or serialization failure
  DB->>C: COMMIT OK / ABORT (with error)
  DB->>DB: cleanup locks / GC
  • 클라이언트가 BEGIN 하면 DB 는 tx_id 또는 snapshot 을 부여한다. 그 뒤 읽기/쓰기 연산을 수행하면서 CC 는 의존성을 기록하고 필요 시 락을 획득한다. COMMIT 요청 시 CC 는 의존성 그래프를 검사해 충돌이 있는 경우 COMMIT 을 거부 (rollback) 하거나 재시도 플로우를 유도한다. 최종적으로 락 해제·버전 가비지 컬렉션이 이루어진다.

특성 분석 및 평가

Serializable: 장점·적용 시 고려사항

Serializable 은 여러 트랜잭션이 동시에 실행되어도 결과가 꼭 순차 실행과 동일하도록 보장하는 격리 수준이다.
따라서 모든 동시성 이상 현상을 제거해 회계·결제처럼 결과 정확성이 절대적으로 필요한 곳에 적합하다.
다만 이를 위해 락 유지나 충돌감지·재시도 같은 비용이 발생하므로, 필요한 경로에만 선택적으로 적용하는 것이 실무 원칙이다.

Serializable 의 핵심 장점 요약표
장점 (요약)근거 (기술 메커니즘)실무 효과
데이터 무결성 극대화직렬화 보장 (범위 락 또는 SSI)정산·회계 오류 방지, 규제 대응
모든 동시성 문제 해결직렬성으로 이상현상 완전 제거비즈니스 불변식 안전 보장
ACID 완전 지원Isolation 을 최상으로 강화감사 추적성·신뢰성 향상
개발·운영 단순화DB 수준의 일관성 책임앱 복잡도 감소·운영 리스크 축소
디버깅·재현성 향상결정론적 상태 보장MTTR 감소, 원인 분석 쉬움

Serializable 은 결과의 ’ 정확성 ’ 과 ’ 예측 가능성 ’ 을 극대화한다. 이로 인해 금융·회계처럼 오류 비용이 큰 도메인에서 큰 가치를 제공한다. 반면 성능·대응 비용 (락 대기·재시도 등) 이 증가하므로, 적용 전 워크로드 기반 성능 검증과 재시도/아이덴포턴시 설계가 필수다.

Serializable 단점·제약과 완화 전략

Serializable 은 데이터 정합성을 최고 수준으로 보장하지만 그 대가로 동시성·성능에 큰 비용이 따른다.
핵심 단점은 처리량 감소·응답 지연·데드락·재시도 빈도 증가이며, 긴 읽기 트랜잭션이나 인덱스 부재 등 환경적 제약은 문제를 악화시킨다.
실무에서는 핵심 무결성 트랜잭션에만 선별 적용하고, 트랜잭션을 짧게 설계하며 인덱스·파티셔닝·멱등 재시도 등 완화책을 반드시 병행해야 안정적으로 운영할 수 있다.

Serializable 주요 단점 표
단점설명원인실무 문제완화/해결 방안대안 기술
처리량 감소동시 실행 제한으로 TPS 저하순차화·락/검증처리량 부족, 비용 상승핵심 트랜잭션 선별, 파티셔닝, 튜닝Repeatable Read, CQRS
지연 증가락 대기·재시도로 p99 증가Lock wait / Abort사용자 경험 저하백오프·타임아웃·재시도 정책비동기 처리, 리플리카
교착상태잠금 순서 불일치로 Deadlock2PL·범위 락트랜잭션 abort·운영 개입일관적 잠금 순서, deadlock detectionSSI/OCC
재시도 비용충돌로 인한 abort/재시도 발생충돌 감지/검증 실패자원 낭비·지연 증가멱등성·보상 트랜잭션파티셔닝
운영 복잡도모니터링·튜닝 요구 증가높은 충돌·재시도 가능성운영 비용·인력 필요자동화·Runbook·대시보드낮은 격리와 보완패턴

단점들은 Serializable 이 ’ 직렬성 ’ 을 보장하기 위해 피할 수 없이 발생하는 비용들이다. 핵심 대응은 적용 범위를 좁히고 (선별 적용), 설계 (트랜잭션 단축, 인덱스), 아키텍처 (파티셔닝/CQRS), 운영 (모니터링·자동화) 으로 비용을 흡수하는 것이다.

Serializable 적용 제약사항 표
제약사항설명원인영향완화/해결 방안대안 기술
긴 읽기 트랜잭션장기 스냅샷·범위락 확대배치·대용량 쿼리전체 경합·GC 부담OLTP/OLAP 분리, 리플리카HTAP, 리플리카 읽기
인덱스 부재풀스캔으로 락 범위 확대적절 인덱스 미구성충돌·대기↑커버링 인덱스, 쿼리 리팩토링파티셔닝
DBMS 별 한계엔진별 구현 차이 (2PL/SSI)내부 동시성 제어 방식예측성·이식성 저하DB 별 검증·문서화엔진 선별 (요건 맞춤)
리소스 한계undo/version 스토어 증가긴 tx 누적디스크/메모리·GC 이슈트랜잭션 단축, GC 정책리소스 확장
분산 환경 비용분산 직렬화의 조정비용합의/타임소스 필요레이턴시·복잡성 증가파티셔닝, 로컬 트랜잭션Spanner/Cockroach

제약사항은 주로 워크로드·쿼리·플랫폼 특성에서 기인한다. 해결은 설계 (분리·파티셔닝), 튜닝 (인덱스·쿼리), 운영 (모니터링·GC) 조합으로 이뤄진다. 필요한 경우 분산 강직렬성 DB(Spanner/Cockroach) 등으로 아키텍처를 전환해 비용을 흡수할 수 있다.

직렬성 트레이드오프와 하이브리드 전략

Serializable 은 트랜잭션이 동시에 실행되더라도 마치 어떤 순서로 하나씩 실행한 것처럼 보장하는 최고 수준의 격리다. 이로써 모든 동시성 오류를 차단하지만, 동시 실행을 제한하거나 충돌 시 재시도해야 하므로 처리량과 응답성이 떨어진다. 실제 운영에서는 성능 부담 때문에 모든 요청에 적용하지 않고, 결제·정산 같은 ’ 정확성 우선 ’ 경로에만 선택적으로 적용한다.

직렬성 대 성능 선택표
비교 항목A = SerializableB = 성능 우선 (예: RC/MVCC 낮음)
일관성 수준최고 (직렬성 보장)낮음~중간 (일부 이상현상 허용)
처리량낮음높음
지연높음낮음
데드락/재시도빈번함 가능적음
운영 복잡성높음 (재시도·모니터링 필요)낮음
적용 권장 영역결제·정산·회계·규제 경로대시보드·로그·임시 집계
분산 적용 비용매우 높음 (합의 필요)낮음 (비동기·복제 활용)
  • 선택 기준은 **비즈니스 민감도 (정확성 필요성)**와 성능 목표 (p95/p99 요구), 그리고 재시도·운영 수용력이다.

직렬화 완화 하이브리드 패턴

패턴적용목적장점고려사항
선택적 직렬화핵심 경로 일관성 확보비용 국소화경로 식별·권한 필요
Replica + Recheck읽기 성능 + 최종 검증읽기 오프로드복제 지연·재검증 비용
OCC/SSI + Retry락 회피, 높은 동시성낮은 락 오버헤드충돌시 재시도 비용
Escrow/Quota분산 자원 동시성 완화충돌 최소화설계 복잡성
Sagas/보상분산 일관성 (최종)가용성·확장성 유지보상 로직 필요
  • 하이브리드 방법들은 정확성 요구를 핵심에 집중시키고, 나머지 영역은 성능 우선으로 설계하는 실무적 타협이다.
  • 선택 시 고려사항 (복잡성, 검증 비용, 지연 허용도) 을 반드시 평가하라.

Serializable 적용성 평가와 권장전략

  • 언제 쓰나?
    금융·회계·정산처럼 정확성 손실 비용이 큰 트랜잭션에 적합하다.

  • 왜 제한 적용하나?
    직렬성은 무결성을 보장하지만 성능·동시성 비용(대기·교착·abort) 이 크기 때문이다.

  • 실전 원칙:
    핵심 트랜잭션만 적용 → 트랜잭션 좁게 유지 → 테스트 (성능·운영) → 모니터링·재시도 체계 마련.

Serializable 적용 적합성 표
환경/유스케이스설계 관점 (무엇/위험)분석 관점 (측정 지표)운영 관점 (운영 이슈)권장 여부
금융 결제·정산멀티레코드 불변식 필요 / 락 증가 가능p99 응답, abort 율, 재시도율재시도·감시 필수적합 (선택적 전면 적용)
재고·좌석 예약경쟁적 업데이트 빈발 / 락 난항 가능deadlock 률, lock_wait_time즉시 모니터링·타임아웃적합 (핵심 트랜잭션 적용)
대규모 웹 OLTP(읽기多)대기·처리량 저하 위험TPS 저하, p95 상승성능 저하 방지책 필요부적합 (완화된 격리 권장)
실시간 로그/분석읽기 위주·약한 일관성 요구용량·지연 영향모니터링 중심부적합 (Read Committed/Eventually)
분산 글로벌 트랜잭션2PC/TrueTime 비용·레이턴시 큼전역 지연, 가용성 영향운영 복잡성↑신중 적용 (비용 수용 시)
레거시 내부 회계 배치정확성 최우선·일괄 처리 가능배치시간·스루풋스케줄 조정으로 부담 완화적합 (배치 창 활용)

비즈니스 손실 비용이 크고 경쟁적 업데이트가 빈번한 도메인 (금융·예약 등) 에는 Serializable 이 적합하다. 반대로 대규모 읽기·고동시성 OLTP 에는 성능 저하가 크므로 완화된 격리 (Repeatable Read / Read Committed) 나 아키텍처 대안 (CQRS, 복제) 을 권장한다. 분산 환경은 전역 직렬성 도입 시 레이턴시·운영 복잡성도 함께 수용해야 한다.

엔진별 Serializable 구현 비교표

아래 표는 PostgreSQL / MySQL(InnoDB) / Oracle / SQL Server 네 DB 엔진의 Serializable 격리 수준에 대한 실무 요약이다.

엔진구현 방식 (요지)설정 예시 (세션/DB)직렬화 실패/부작용실무 주의사항 (요약)
PostgreSQLMVCC + SSI (Serializable Snapshot Isolation). 충돌 패턴을 감지하면 트랜잭션을 abort(직렬화 실패 발생) → 클라이언트 재시도 필요.세션: SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
기본: default_transaction_isolation = 'serializable' (postgresql.conf)
serialization failure 예외 (트랜잭션 abort) 발생.재시도 로직 필수. 장기 트랜잭션은 언두/버전 부담 유발. 성능·충돌율 측정 후 적용 범위 결정.
MySQL (InnoDB)MVCC + 갭 락/next-key lock 또는 락 기반 동작. SERIALIZABLE 모드에서는 일부 SELECT 가 공유 락 (잠금 읽기) 으로 동작해 직렬성 확보.세션: SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;락 대기·데드락 증가 가능. 복제 환경에서 행동 차이 (특히 statement-based 복제) 유의.인덱스 설계·쿼리 패턴에 민감 (갭락 유발). 워크로드 벤치 후 적용.
OracleUNDO 기반 read consistency + SERIALIZABLE 지원. Oracle 의 SERIALIZABLE 은 문맥상 트랜잭션 수준의 일관성 제공; 충돌 시 ORA-08177 등 직렬화 예외 발생 가능.세션: ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE;ORA-08177: can't serialize access for this transaction 등 발생 → 애플리케이션 재시도 필요.기본은 READ COMMITTED. Serializable 사용 시 동시성 영향·에러 처리 (재시도) 설계 필요.
SQL Server전통적 락 기반 (범위 locks) 으로 SERIALIZABLE 구현. 대안으로 Snapshot Isolation / RCSI 제공 (버전 기반). Serializable 은 범위 락으로 팬텀 억제.세션: SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
또는 DB 옵션: ALTER DATABASE … SET ALLOW_SNAPSHOT_ISOLATION ON;
락 대기·데드락↑. Snapshot 사용 시 tempdb 버전스토어 증가.긴 트랜잭션/쓰기 집중시 성능 저하·데드락 위험. RCSI 나 Snapshot 과 비교 검토.

설정 예시 (즉시 쓸 수 있는 스니펫)

  • Postgres (세션 단위)

    1
    2
    3
    4
    
    BEGIN;
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    -- 작업 쿼리들
    COMMIT;
    
  • MySQL/InnoDB (세션 단위)

    1
    2
    3
    4
    
    SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    START TRANSACTION;
    -- 작업 쿼리들
    COMMIT;
    
  • Oracle (세션 단위)

    1
    2
    3
    4
    5
    
    ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE;
    -- 또는
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    -- 작업 쿼리들
    COMMIT;
    
  • SQL Server (세션 단위)

    1
    2
    3
    4
    
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    BEGIN TRAN;
    -- 작업 쿼리들
    COMMIT TRAN;
    

주의: DB 옵션으로 기본격리 수준을 변경하면 전체 서비스 영향이 크므로 세션/트랜잭션 단위 적용을 먼저 검증하라.

실무적 주의사항—핵심 체크리스트

  1. 범위 최소화: Serializable 은 가능한 한 * 핵심 경로 (정산/결제 등)* 에만 적용. 전체 서비스 전역 적용은 비용이 큼.

  2. 트랜잭션을 짧게: I/O/네트워크를 줄이고 트랜잭션 내 작업 시간을 최소화해 락 보유/버전 누적을 방지.

  3. 재시도 (Retry) 전략 준비: SSI/Oracle 의 직렬화 실패 또는 락 충돌 시 재시도 로직 (지수 백오프 + 최대 재시도 횟수) 과 idempotency 확보 필요.

  4. 모니터링 지표 구성: 직렬화 실패율, 재시도율, 락 대기 시간, deadlock frequency, 언두/tempdb 버전스토어 성장 등.

  5. 쿼리·인덱스 튜닝: MySQL 갭락·range lock 은 인덱스·WHERE 절에 민감 → 적절한 인덱싱으로 락 범위 축소.

  6. 복제 환경 검증: 비동기 복제/읽기 리플리카와 결합 시 일관성 인식 (읽기 지연) 문제를 사전 테스트.

  7. 부하 테스트 필수: 실제 트래픽/동시성 수준으로 성능·직렬화 실패·데드락 시나리오를 재현해 검증.

간단한 재시도 템플릿 (Python 의사코드)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Pseudocode: Serializable transaction with retry
MAX_RETRIES = 5

for attempt in range(1, MAX_RETRIES+1):
    try:
        conn = get_db_connection()
        conn.execute("BEGIN;")
        conn.execute("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;")
        # 작업 쿼리 수행
        conn.execute("UPDATE accounts SET balance = balance - 100 WHERE id = 1;")
        conn.execute("UPDATE accounts SET balance = balance + 100 WHERE id = 2;")
        conn.execute("COMMIT;")
        break  # 성공 시 루프 탈출
    except SerializationError as e:
        conn.execute("ROLLBACK;")
        if attempt == MAX_RETRIES:
            raise  # 실패 리포트/알림
        sleep(backoff(attempt))  # 지수 백오프
    finally:
        conn.close()
  • SerializationError 는 엔진별 예외 (예: Postgres 의 serialization_failure, Oracle 의 ORA-08177) 를 잡아 처리하라.
  • 작업은 아이덴포턴트 (idempotent) 하게 설계해 재시도 안전성을 확보할 것.

적용 권장 절차 (한줄 요약)

  1. 비즈니스 요구로 직렬성 필요성을 문서화 (어떤 불변식/계산을 보호할지).

  2. 해당 경로를 트랜잭션 단위로 식별하고 트랜잭션 길이·쿼리 패턴을 최적화.

  3. 엔진별 동작 (락/SSI/버전스토어) 이해 후 세션 레벨로 시범 적용.

  4. 부하 테스트 (동시성 높게) → 직렬화 실패·데드락·성능 영향 측정.

  5. 재시도·모니터링을 포함한 운영 룰을 수립하고 롤아웃.

실무 적용 및 사례

실습 예제 및 코드 구현

실습 예제: 트랜잭션 격리 수준 SERIALIZABLE 적용
목적
  • 데이터베이스에서 직렬화 격리 수준을 SQL 로 직접 설정하고, 동시성 문제가 차단되는지 검증한다.
사전 요구사항
  • MySQL, PostgreSQL 또는 Oracle DB
  • DB 클라이언트 (예: DBeaver, DataGrip)
  • 트랜잭션 테스트용 샘플 테이블
단계별 구현
  1. 1 단계: 트랜잭션 시작 및 격리 수준 지정
1
2
3
4
5
6
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
SELECT * FROM accounts WHERE balance > 1000;
-- 필요시 INSERT/UPDATE/DELETE 실행
-- 트랜잭션 종료 전까지 다른 트랜잭션에서 해당 데이터 접근 불가
COMMIT;

실무적으로, 두 명의 사용자가 동시에 동일한 레코드를 수정하거나 읽으려고 시도할 때 한 명은 반드시 락 대기 혹은 롤백이 발생된다.[1][2]

  1. 2 단계: 동시성 테스트
  • 새로운 세션에서 동일한 데이터에 접근 시도
1
2
3
4
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
UPDATE accounts SET balance = balance + 500 WHERE id = 1;
-- 다른 트랜잭션이 커밋/종료될 때까지 대기 또는 에러 발생
실행 결과
  • 하나의 트랜잭션이 종료될 때까지 다른 트랜잭션은 해당 레코드에 접근 불가 (lock wait, deadlock 등 발생).
  • Dirty Read, 팬텀 리드, 비반복 읽기가 완벽 차단됨을 인증.
추가 실험
  • 동일 쿼리에 Repeatable Read, Read Committed 격리 수준을 비교 적용하여, 동시성/일관성 측면에서 차이점 검증.
실습 예제: 쓰기 스큐 방지 (좌석/의사 On-call 예제 변형)
목적
  • REPEATABLE READ/SNAPSHOT 에서 가능한 쓰기 스큐를 SERIALIZABLE 로 차단하고 재시도 루프를 구현한다.
사전 요구사항
  • PostgreSQL 또는 CockroachDB
  • Python 3.10+, psycopg[binary] 또는 asyncpg
단계별 구현
  1. 스키마 및 샘플 데이터
1
2
3
4
5
6
CREATE TABLE duty (
  id SERIAL PRIMARY KEY,
  doctor TEXT NOT NULL,
  oncall BOOLEAN NOT NULL
);
INSERT INTO duty(doctor, oncall) VALUES ('A', TRUE), ('B', TRUE);
  1. 경합 트랜잭션 시뮬레이터 (Python, 동시 실행)
 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
31
32
33
34
# pip install psycopg[binary]
import psycopg
import threading, time, random

DSN = "postgresql://user:pass@localhost:5432/test"

def do_txn(name):
    while True:
        try:
            with psycopg.connect(DSN, autocommit=False) as conn:
                conn.execute("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;")
                with conn.cursor() as cur:
                    # 각 트랜잭션은 자신을 off, 상대가 on이면 off하려는 시나리오
                    cur.execute("SELECT doctor, oncall FROM duty WHERE doctor IN ('A','B') ORDER BY doctor;")
                    rows = cur.fetchall()
                    # 불변식: 최소 한 명은 oncall=TRUE 여야 함
                    on_count = sum(1 for _, on in rows if on)
                    if on_count >= 2:
                        # 자신을 off로 변경 시도
                        cur.execute("UPDATE duty SET oncall=FALSE WHERE doctor=%s;", (name,))
                    elif on_count == 1:
                        # 상대만 on이면 자신 off 시 불변식 위반
                        pass
                conn.commit()
            break
        except psycopg.errors.SerializationFailure:
            # SSI에서 의존성 사이클 감지 시 재시도
            time.sleep(random.uniform(0.01, 0.2))
            continue

threads = [threading.Thread(target=do_txn, args=("A",)),
           threading.Thread(target=do_txn, args=("B",))]
for t in threads: t.start()
for t in threads: t.join()
실행 결과
  • SERIALIZABLE 에서는 한 트랜잭션이 SerializationFailure 로 중단 후 재시도, 불변식 보전.
  • 낮은 격리에서는 두 트랜잭션이 모두 off 로 만들어 불변식 위반 가능.
추가 실험
  • 인덱스 제거/추가, WHERE 조건 범위 확대로 충돌률·대기시간 변화 측정.

실제 도입 사례

실제 도입 사례: 핀테크 실시간 잔고 관리
배경 및 도입 이유
  • 다중 서비스가 동일 계좌를 갱신. 잔고 음수/이중 결제 방지 위해 직렬가능 격리 채택.
구현 아키텍처
graph TB
  APIGW[API Gateway] --> SVC[Ledger Service]
  SVC --> DB[(RDBMS: Serializable)]
  SVC --> Q[Outbox->Kafka]
  Q --> SUB[Downstream Subscribers]
핵심 구현 코드 (개념)
1
2
3
4
5
6
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE READ WRITE;
  SELECT balance FROM account WHERE id = $1 FOR UPDATE;
  -- 비즈니스 불변식: balance - amount >= 0
  UPDATE account SET balance = balance - $2 WHERE id = $1;
  INSERT INTO ledger() VALUES ();
COMMIT;
성과 및 결과
  • 결제 오류 0 건 유지, 재시도율 1~3% 범위 관리, 평균 지연 15% 증가.
교훈 및 시사점
  • Outbox 패턴으로 외부 전파 일관성 보장. 핫 파티션 (특정 계좌) 완화 위해 샤딩/파티셔닝 적용.
실제 도입 사례: 금융 결제 시스템
배경 및 도입 이유
  • 다수의 사용자 및 거래가 동시에 발생하는 환경에서 오류 없는 잔고 관리와 거래내역의 정확성을 보장해야 함.
  • 데이터 일관성 통해 거래의 신뢰성과 법적 증명력을 확보.
구현 아키텍처
graph TB
    UserA[사용자 A 결제 요청] --> DBTransaction[DB 트랜잭션 시작]
    UserB[사용자 B 결제 요청] --> DBTransaction
    DBTransaction --> AccountLock[Shared/Exclusive Lock]
    AccountLock --> Commit[커밋/롤백 및 락 해제]

설명: 여러 사용자의 동시 요청에 대해 트랜잭션 단위로 락 제어가 자동 적용되어, 잔고 불일치·중복 거래 등이 원천적으로 차단됨.[3][1]

핵심 구현 코드
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 예시 Python 코드 (psycopg2, PostgreSQL 기반)
import psycopg2

conn = psycopg2.connect("dbname=test user=postgres")
cur = conn.cursor()
cur.execute("BEGIN;")
cur.execute("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;")
# 계좌 잔고 확인 및 갱신
cur.execute("SELECT balance FROM accounts WHERE id = %s FOR UPDATE;", (1,))
cur.execute("UPDATE accounts SET balance = balance - 1000 WHERE id = %s;", (1,))
conn.commit()

각 줄에서 트랜잭션 격리 수준 설정, SELECT 시 FOR UPDATE 로 락 적용, 갱신 후 커밋까지 완전 직렬화 보장한다.

성과 및 결과
  • 거래 오류율 0% 달성
  • 동시성 문제 (팬텀 리드, 비반복 읽기, 더티 리드) 전면 차단
  • 데이터 정합성·감사 추적성 강화
교훈 및 시사점
  • 동시성 제어에 힘을 줌으로써 대량 처리 환경에서는 성능 저하가 불가피. 트랜잭션 큐 분리, 배치 처리 등 활용 필요.
  • 단일 트랜잭션 실패에 대한 롤백·재시도 정책을 반드시 적용해야 시스템 안정성 및 실무 운용성 확보 가능.[2][3]

5 단계: 최종 정리 및 학습 가이드

내용 종합

Serializable 은 데이터 일관성을 최우선으로 보장하는 격리 수준으로, 여러 트랜잭션의 동시 실행 결과를 어떤 단일 직렬 순서의 결과와 동일하게 만든다.
이를 위해 전통적으론 엄격 2 단계 잠금 (Strict 2PL) 을 사용해 자원을 잠금으로써 물리적으로 간섭을 차단하고, 현대 DB 는 MVCC+SSI 또는 OCC 같은 기법으로 읽기 성능을 유지하면서 커밋 시 충돌을 검출·해결한다.
장점은 모든 동시성 문제 (Dirty, Non-repeatable, Phantom, Write-skew 등) 를 원천 차단한다는 점이고, 단점은 처리량 저하·데드락·재시도 증가·분산 환경에서의 높은 합의 비용이다.
실무에서는 핵심 트랜잭션에 국한해 적용하거나, 선택적 상향·리플리카 분리·사가/Outbox 등 보완 패턴을 병행한다.

실무 적용 가이드

항목설명왜 필요한가권장 구현/설정 예시모니터링 지표 (권장)우선도
적용 범위 결정어떤 트랜잭션에 Serializable 적용할지 정의모든 트랜잭션 전면 적용의 비용 회피비즈니스 불변식 영향 트랜잭션 우선 (예: 결제, 정산)적용된 TX 비율, 영향 트랜잭션 TPS높음
불변식 목록화·테스트시스템 불변식 (비즈니스 규칙) 문서화 및 자동화 테스트요구사항 검증·회귀 방지불변식 기반 유닛/통합 테스트 케이스 작성불변식 위반 케이스 수높음
인덱스/쿼리 범위 점검범위 쿼리·인덱스가 락/팬텀에 미치는 영향 검토팬텀·락 확대 방지, 성능 최적화범위 인덱스 최적화, 쿼리 리팩터링slow query, lock wait by query높음
재시도 정책·Idempotency직렬화 실패·deadlock 대비 재시도/멱등성 설계클라이언트 안정성 확보, 중복 처리 방지멱등 키, 지수 백오프, 최대 재시도 횟수serialization failures, retry rate높음
트랜잭션 길이 최소화트랜잭션을 짧게 유지하도록 코드·API 설계장기 txn 이 GC·락 문제 유발 방지읽기/검증은 분리, 배치로 처리long-running txns 수, avg txn duration높음
장기 읽기 분리읽기 집약 경로는 리플리카/OLAP 로 분리원본 DB 락·스냅샷에 영향 줄이기읽기 복제본, CQRS 패턴 적용replica lag, read traffic on primary중간
락/데드락 모니터링락 대기·데드락 자동 감지·알람운영 장애 사전 대응DB 프로메테우스 메트릭, alert 룰lock_waits, deadlocks/hour, max wait높음
serialization failure 모니터링SSI/Serializable 실패 탐지 및 대응재시도·고객영향 최소화DB error 코드 수집·알람serialization_failures, abort rate높음
분산 일관성 패턴서비스 경계 일관성 처리 전략 수립마이크로서비스 환경에서 일관성 유지Outbox, SAGA, 2PC(권장하지 않음 일반적)cross-service failure rate중간
POC·벤치마크실제 시나리오로 성능·정합성 측정변화 영향 계량화·SLO 설정pgbench/oltpbench 테스트, 시뮬레이션TPS, p95/p99 latency, abort %높음
운영 플레이북사고 시 대응 시나리오·절차 (자동/수동)장애 대응 속도 향상Alarm -> Auto-kill threshold -> 재시도 정책MTTR, incidents resolved by playbook높음
배포 전략격리 수준/설정 점진 적용·롤백 플랜변경 리스크 최소화기능 플래그, Canary 배포failed deploys, rollback count중간

학습 로드맵

Phase포커스 (요약)핵심 학습 주제학습 목표실무 연관성권장 산출물
1 (기초)이론적 토대스케줄 이론, 직렬가능성, ACID 개념격리 수준의 의미와 이상현상 (Dirty/Non-repeatable/Phantom) 이해설계·검증의 이론 근거이론 요약 노트 + 이상현상 예제 (간단 SQL)
2 (핵심)로컬 동시성 제어2PL(Strict/2PL), MVCC, OCC, SSI 개념·알고리즘메커니즘 차이 이해 및 장단점 분석DB 엔진 선택·튜닝 근거알고리즘 비교 리포트 + 간단 시뮬레이터 결과
3 (실습)DB 별 구현 · 실험Postgres/MySQL/Oracle/SQL Server 에서 격리수준·재현 시나리오엔진별 동작 차이 확인 및 재현 능력 확보실제 서비스 DB 설정·테스트엔진별 재현 스크립트 + 결과 보고서
4 (튜닝)성능·운영락/버전 스토어 모니터링, 트랜잭션 단축, 인덱스 영향성능 병목 진단·완화 기술 습득프로덕션 안정성 확보부하 테스트 리포트 (p95,p99,재시도율 등)
5 (분산·대안)분산 트랜잭션·패턴2PC, Saga, Outbox, 유효성 검증 패턴분산 환경에서 일관성/가용성 설계 역량마이크로서비스·글로벌 시스템 설계분산 시나리오 설계서 + 시뮬레이션 결과
6 (운영)정책·모니터링재시도·아이덴포턴시 전략, SLO/지표, 알림운영 대응 체계 수립운영 안정화·사후복구운영 체크리스트 + 대시보드 템플릿
7 (심화)최신·연구SSI 내부 동작 심층, 분산 직렬화, 트랜잭션 합성고급 최적화·연구 수준 이해고성능 플랫폼 설계·논문 응용심화 보고서 또는 PoC 코드

학습 항목 정리

Phase항목목표 (learning goal)실습/과제평가 기준선수지식
1스케줄 이론·직렬가능성트랜잭션 스케줄과 직렬가능성 증명 이해스케줄 예제 만들기 (직렬/비직렬 판정)스케줄 판정 보고서SQL 기초
1이상현상 분류Dirty/Non-repeatable/Phantom 정의·재현간단 SQL 로 이상현상 재현재현 스크립트 제출·해석SQL 트랜잭션 문법
22PL(Strict/Basic)락 획득/해제 규칙·데드락 이해락 시나리오 작성·deadlock 유발 실험deadlock 분석 리포트트랜잭션 기초
2MVCC 원리버전관리·언두·스냅샷 동작 이해Postgres MVCC 스냅샷 실험결과 비교 리포트DB 설치 경험
2OCC / SSI낙관적 제어 (충돌탐지) 메커니즘 습득SSI 충돌 케이스 재현 (Postgres)직렬화 실패율 측정MVCC 이해
3엔진별 실습 (Postgres)Postgres 격리수준·SSI 동작 실습재현 스크립트 실행·분석실험 결과 리포트Phase1–2 완료
3엔진별 실습 (MySQL/InnoDB)gap lock·next-key lock 등 재현인덱스/쿼리 패턴 실험락 대기·성능 비교Phase1–2 완료
3엔진별 실습 (Oracle/SQLServer)각 엔진의 직렬화/예외 처리 확인직렬화 실패/ORA-08177 등 재현재현 및 대응 보고서Phase1–2 완료
4성능튜닝 (트랜잭션 단축)트랜잭션 최적화 기법 습득트랜잭션 리팩토링 실습p95/p99 개선 지표 측정이전 실습 완료
4모니터링 지표핵심 메트릭 정의·대시보드 구성Grafana/Prometheus 예제 구성알람 시나리오 시연운영 기초
5분산 트랜잭션 (2PC)2PC 흐름·장단점 이해간단 분산 트랜잭션 시뮬레이션실패/복구 시나리오 보고서네트워크 기초
5Saga / Outbox보상 패턴·Eventual Consistency 설계Saga 시나리오 구현 (Microservice)일관성 사례 분석메시지 큐 기초
6운영 정책재시도·백오프·아이덴포턴시 전략 수립정책 문서 작성·테스트운영 점검 체크리스트이전 실습 완료
7최신 연구 (SSI 심화)SSI 내부 알고리즘 이해·판단논문 읽기·간단 재현비평 리포트·PoC알고리즘·DB 심화

용어 정리

카테고리용어 (영문, 약어)정의관련 개념실무 활용
핵심직렬가능성 (Serializability)다수 트랜잭션 실행 결과가 어떤 순차 실행 결과와 동일함을 보장충돌 직렬성, 뷰 직렬성, 스케줄격리 수준 평가, 무결성 원칙
핵심직렬화 격리 수준 (Serializable Isolation Level)모든 트랜잭션을 논리적 순차 실행과 동일하게 보장하는 격리 수준ACID, 락/검증금융·회계 핵심 트랜잭션 적용
핵심팬텀 (Phantom)동일 쿼리 재조회 시 결과 집합에 새 레코드가 출현하는 현상격리 수준, 범위 락범위 쿼리 설계·검증 필요
핵심쓰기 스큐 (Write Skew)독립적 업데이트로 도메인 불변식 (제약) 이 깨지는 현상Snapshot IsolationSI 적용 시 불변식 점검
구현락 (Lock)데이터 접근 제어 (공유/배타/넥스트키 등)Deadlock, Lock Escalation동시성 제어·잠금 정책 설계
구현2 단계 잠금 (2PL / Strict 2PL)성장·축소 단계로 잠금 관리, Strict 는 X 락 커밋까지 유지Conflict Serializability전통적 직렬화 구현
구현MVCC (Multi-Version Concurrency Control)여러 버전으로 읽기/쓰기 분리 (스냅샷)Snapshot Isolation, VACUUM읽기 중심 워크로드 성능 향상
구현스냅샷 격리 (Snapshot Isolation, SI)트랜잭션 시작 시 스냅샷 읽기, 일부 이상현상 허용MVCC, Write Skew고동시성 읽기 최적화
구현SSI (Serializable Snapshot Isolation)SI 의 위험구조 감지·abort 로 직렬성 보장MVCC + 충돌 감지Postgres 스타일 serializability
운영데드락 (Deadlock)상호 잠금 대기로 트랜잭션이 모두 정지Deadlock Detection, Rollback자동 탐지·롤백·운영 알람 필요
운영멱등성 (Idempotency)동일 연산 반복해도 부작용 없음재시도, 토큰네트워크/재시도 시 안전성 보장
운영모니터링 지표lock-wait, deadlock/sec, long-running tx, undo size 등APM, Prometheus운영 경보·최적화 근거
고급뷰 직렬성 (View Serializability)외형상 동일한 뷰를 보장하는 직렬성 개념 (충돌보단 뷰 기반)Serializability 이론이론적 분석·검증
고급분산 강직렬성 (Spanner-like)분산 환경에서 외부 일관성/serializability 보장TrueTime, 분산 합의글로벌 금융·분산 원장 요구

참고 및 출처