
백엔드
실무에서 만나는 DB isolation level
두줄요약
MySQL 기본 격리 수준인 REPEATABLE READ 때문에 결제 트랜잭션에서 오래된 잔액이 유지되는 문제를 겪었습니다. 락 위치와 격리 수준을 조정해 동시성 이슈를 해결하는 과정을 정리했습니다.
문제 상황
- Oracle 기반에서 MySQL로 전환한 신규 결제 시스템에서 동시 요청 처리 중 잔액 업데이트 실패 발생
- 락 획득 전 잔액 조회 로직 추가 이후, 뒤늦게 들어온 요청이 이전 잔액을 계속 참조하는 현상 확인
원인 분석
- MySQL 기본 격리 수준인 REPEATABLE READ 영향으로 트랜잭션 내 첫 조회 값이 끝까지 유지
- 락 대기 이후에도 최신 커밋값 대신 처음 읽은 잔액을 계속 사용하며 정합성 문제 발생
해결 방법
- 잔액 조회를 DB 락 이후로 옮겨 커밋된 데이터만 읽도록 변경
- 트랜잭션 격리 수준을 READ COMMITTED로 조정하는 방법 검토
- DBMS별 기본 격리 수준과 지원 범위 차이 확인 필요
