Q.트랜잭션 격리 수준 4가지를 설명해주세요
| 수준 | 더티 리드 | 반복 불가 | 팬텀 |
|---|
| READ UNCOMMITTED | 발생 | 발생 | 발생 |
| READ COMMITTED | 막음 | 발생 | 발생 |
| REPEATABLE READ | 막음 | 막음 | 발생 (InnoDB 는 대체로 막음) |
| SERIALIZABLE | 막음 | 막음 | 막음 |
위로 갈수록 안전하고 아래로 갈수록 동시성이 좋습니다. 격리를 강하게 하면 잠금 범위가 넓어져 대기가 늘어납니다.
각 이상 현상이 뜻하는 것입니다.
| 현상 | 뜻 |
|---|
| 더티 리드 | 커밋되지 않은 값을 읽는다. 롤백되면 없던 값을 본 셈 |
| 반복 불가 | 같은 행을 두 번 읽었는데 값이 달라진다 |
| 팬텀 | 같은 조건으로 두 번 조회했는데 행 수가 달라진다 |
흔한 실수: SERIALIZABLE 을 기본으로 쓰자고 답하는 것. 동시성이 크게 떨어져 처리량이 무너집니다. 대부분의 서비스는 READ COMMITTED 나 REPEATABLE READ 로 충분합니다.
Q.실무에서 주로 어떤 격리 수준을 쓰나요?
대부분 기본값을 그대로 씁니다. MySQL 은 REPEATABLE READ, PostgreSQL 과 Oracle 은 READ COMMITTED 입니다.
| 상황 | 선택 |
|---|
| 일반 조회와 갱신 | 기본값 |
| 같은 트랜잭션에서 같은 데이터를 여러 번 읽어야 한다 | REPEATABLE READ |
| 정확성이 돈과 직결된다 | 해당 구간만 명시적 잠금이나 SERIALIZABLE |
| 통계나 리포트 | READ COMMITTED 로 충분. 오히려 잠금을 줄인다 |
중요한 것은 격리 수준을 전역으로 올리기보다 필요한 트랜잭션에만 강하게 거는 것입니다. 재고 차감이나 좌석 예약처럼 정확성이 필요한 구간에 SELECT ... FOR UPDATE 를 쓰는 방식이 흔합니다.
흔한 실수: 격리 수준만으로 모든 동시성 문제가 해결된다고 보는 것. 읽고 계산해서 쓰는 흐름은 격리 수준과 별개로 잠금이나 조건부 갱신이 필요합니다.
Q.MySQL과 PostgreSQL의 기본 격리 수준 차이는?
| DB | 기본값 | 이유 |
|---|
| MySQL InnoDB | REPEATABLE READ | 복제 방식의 역사적 이유. 문장 기반 복제에서 일관성을 지키려면 필요했다 |
| PostgreSQL | READ COMMITTED | 동시성을 우선. 대부분의 애플리케이션에 충분하다 |
같은 이름이어도 동작이 다릅니다. InnoDB 의 REPEATABLE READ 는 갭 잠금으로 팬텀까지 대체로 막지만, 표준에서는 팬텀이 허용됩니다. PostgreSQL 의 REPEATABLE READ 는 스냅샷 격리로 구현돼 팬텀이 생기지 않습니다.
그래서 DB 를 옮길 때 격리 수준 이름만 맞추면 동작이 같을 것이라고 가정하면 안 됩니다.
흔한 실수: 표준 정의만 외워 답하는 것. 실제 제품의 구현이 표준과 다른 지점이 이 질문의 핵심입니다.
먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.
읽었으면 문제로 확인해보세요
데이터베이스 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.