DEV/Spring Data JPA

데이터베이스 트랜잭션과 락 2

행운개발자 2024. 3. 19. 00:23
728x90

트랜잭션의 격리 수준

  DIRTY READ NON-REPEATABLE READ PHANTOM READ
1. READ UNCOMMITTED O O O
2. READ COMMITTED   O O
3. REPREATABLE READ     O
4. SERIALIZABLE      

 

1. READ UNCOMMITTED

커밋되지 않은 데이터를 읽을 수 있습니다. 여러개의 트랜잭선이 동시에 수행되고 있을 때, 다른 트랜잭션에서 수정하고 아직 커밋하지 않은 데이터를 조회할 수 있습니다. 이를 DIRTY READ라고 합니다. 트랜잭선 A에서 수정하고 커밋하지 않은 데이터가 트랜잭션 B에서 DIRTY READ된 뒤에 커밋되지 않고 롤백된다면 데이터 정합성에 문제가 발생할 수 있습니다.

2. READ COMMITTED

커밋된 데이터만 읽을 수 있습니다. 트랜잭션 A에서 데이터를 수정하기 전에 트랜잭션 B에서 데이터를 조회했습니다. 트랜잭션 A가 데이터를 수정하고 커밋하고 다시 트랜잭션 B가 데이터를 조회하면 이전에 조회한 데이터와 다른 데이터가 조회됩니다. (NON-REPREATABLE READ)

3. REPREATABLE READ

한 번 조회한 데이터는 반복해서 조회해도 같은 데이터가 조회됩니다. 하지만 트랜잭션 A가 나이가 10살 이하인 유저를 조회를 하고 있는데, 트랜잭션 B에서 나이가 5살인 유저를 한 명 추가합니다. 그러면 트랜잭션 A에서 다시 조회했을 때 회원 하나가 추가된 상태로 조회됩니다. 반복 조회시 결과 집합이 달라지는 것은 PHANTOM READ라고 부릅니다.

4. SERIALIZABLE

가자 엄격한 트랜잭션 격리 수준입니다. PHANTON READ까지 발생하지 않지만, 동시성 처리 성능이 급격하게 떨어집니다.

일반적인 경우에는

보통 READ COMMITTED를 기본으로 사용합니다. 일부 중요한 비즈니스 로직에서는 트랜잭션 격리 수준을 높이기보다 데이터베이스에서 제공하는 LOCK의 개념을 사용합니다.

낙관적 락과 비관적 락

JPA의 영속성 컨텍스트 (1차 캐시)를 적절히 활용하면 데이터베이스 트랜잭션이 READ COMMITTED 격리 수준이어도 애플리케이션 레벨에서도 REPREATABLE READ가 가능합니다.

JPA가 제공하는 낙관적 락은 버전(@version)을 사용합니다. 낙관적 락은 트랜잭션을 커밋하는 시점에 충돌을 알 수 있다는 특징이 있습니다. JPA가 제공하는 비관적 락은 데이터베이스 트랜잭션 락 메커니즘에 의존하는 방법입니다. 주로 SQL 쿼리에 select for update 구문을 사용하면서 시작하고 버전 정보는 사용하지 않습니다.

728x90