면접에서 나왔던 질문이지만, 내가 대답하지 못했던 부분에 대해서 알아보려고 한다.
우선 트랜잭션이 무엇인지, 왜 필요한지는 이미 안다고 생각한다.
그리고 당연히 트랜잭션의 레벨이 높아질수록, 동시성이 떨어지기 때문에 성능이 떨어진다.
하지만 그만큼 고립시켜서 동작하기 때문에 일관성은 높아진다.
우선 크게
Read Uncommitted, Read Committed, Repeatable Read, Serializable
이렇게 4가지로 나뉘며, 오른쪽으로 갈수록 레벨이 높아진다.
- Read Uncommitted
트랜잭션이 처리중이거나, 아직 commit되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용한다.
이렇게 그냥 다른 트랜잭션에서 처리를 하고 있더라도, 데이터를 그냥 조회해서 값을 가져온다.
하지만 조회 후, 데이터가 rollback 되어 버리면 부정확한 데이터를 가져오게 된다.
이런 Dirty Read가 발생할 수 있기 때문에, 정확도가 너무 낮아 표준에서 인정하지 않는 격리 수준이라고 한다.
- Read Committed
커밋된 데이터만 조회할 수 있도록 한다.
그렇기에 다른 트랜잭션이 접근 할 수 없어 대기하게 된다.
그렇기에 commit 되기 전의 데이터를 읽는 Dirty Read는 발생하지 않게 된다.
하지만, 하나의 트랜잭션에서 다른 트랜잭션의 commit에 따라 데이터의 조회 결과가 달라지는 Non-Repeatable Read 문제가 생기게 된다.
그렇지만 자주 발생하는 문제는 아니며, 대부분의 기본 설정이 이 Read Commited라고 한다.
- Repeatable Read
보통의 RDBMS는 변경 전의 데이터를 Undo 공간에 백업해둔다.
그렇기에 트랜잭션의 번호를 확인해, 자신보다 더 늦은 트랜잭션의 번호가 존재한다면 이 Undo 공간에서 데이터를 조회하게 된다.
그렇기 때문에, 다른 트랜잭션에 의해 변경되더라도 동일한 데이터를 조회할 수 있게 된다.
하지만 조회 트랜잭션동안 새로운 데이터가 추가되는 것을 감지하지 못하는 Phantom Read가 발생할 수도 있다고 한다.
그래도 이 Phantom Read는 트랜잭션의 번호를 확인해 무시하는 방법으로 해결 할 수 있으며, 현재의 RDBMS에서는 특정 상황이 아니라면 대부분 발생하지 않는 현상이기에 크게 신경쓰지는 않아도 된다고 한다.
- Serializable
마지막은 가장 강력한 Serializable 레벨이다.
그냥 모든 트랜잭션을 순차적으로 실행시키기에 위에 소개했던 모든 정합성 관련 문제들이 발생하지 않는다.
하지만 동시성이 없어지기에 성능이 매우 떨어진다.
극단적으로 안정성이 필요한 경우가 아니라면 잘 사용하지 않는다고 한다.
'토이 프로젝트' 카테고리의 다른 글
Slack을 이용해서 서버 에러 보고하도록 만들기 (1) | 2025.07.19 |
---|---|
스프링의 AOP @Transactional 알아보기 (0) | 2025.04.11 |
메모리 단편화, 객체 생성 시간을 줄이기 위한 ObjectPool 적용 (1) | 2025.02.11 |
Stomp에서 Jwt Filter 구현하기 (1) | 2025.01.23 |
Hexagonal Architecture 적용하기 (1) | 2025.01.22 |