Quick Reference
SQL 표준의 최소 보장:
READ UNCOMMITTED -> dirty read까지 허용 가능
READ COMMITTED -> dirty read 방지, 반복 조회 변화 가능
REPEATABLE READ -> non-repeatable read 방지, phantom은 허용 가능
SERIALIZABLE -> 직렬 실행과 같은 결과, 충돌 시 abort/retry 가능
PostgreSQL 차이:
READ UNCOMMITTED = READ COMMITTED, REPEATABLE READ도 phantom을 허용하지 않음PostgreSQL은 READ UNCOMMITTED를 READ COMMITTED처럼 처리하고 REPEATABLE READ에서도 phantom read를 허용하지 않습니다. Isolation level 이름이 같아도 구현별 보장이 다르므로 사용하는 제품 문서를 기준으로 확인합니다.
읽기 현상
Dirty read는 commit되지 않은 값을 읽는 현상, non-repeatable read는 같은 row를 다시 읽었을 때 값이 달라지는 현상, phantom은 같은 조건 조회의 row 집합이 달라지는 현상입니다.
MVCC는 reader와 writer의 충돌을 줄이지만 모든 write conflict와 deadlock을 없애지는 않습니다. SELECT ... FOR UPDATE 같은 명시적 lock은 읽은 row를 이후 갱신할 계획이 있을 때 사용하지만 lock 범위를 넓힐 수 있습니다.
표준의 네 단계는 낮은 단계가 무조건 빠르고 높은 단계가 무조건 느리다는 단순 서열이 아닙니다. Snapshot 유지 비용, lock 대기, serialization failure와 재시도 비용이 workload에 따라 달라집니다.
실패와 재시도
Database가 deadlock cycle을 발견하면 transaction 하나를 중단해 순환을 풉니다. Serializable isolation도 직렬화 실패를 반환할 수 있습니다. Application은 transaction 전체를 안전하게 재시도할 수 있어야 하며 외부 side effect를 transaction 안에서 중복 실행하지 않도록 설계합니다.
자주 틀리는 점
- 높은 isolation을 설정하면 application invariant가 자동으로 완성된다고 생각하지 않습니다.
- Lock 순서를 다르게 잡는 code path를 만들지 않습니다.
- Deadlock victim 오류를 단순 네트워크 오류처럼 transaction 중간부터 재개하지 않습니다.
- 긴 transaction과 대량 update의 lock·version 영향을 확인합니다.
참고 링크
2 sources