자바/리팩토링
[리팩토링]동시성 문제 - 읽기 3가지
OverTheHorizon3410
2023. 10. 24. 22:11
- 더티 리드 (Dirty Read)
- 트랙잭션 A 가 아직 커밋되지 않은 변경을 만든 경우,
- 트랜잭션 B 가 해당 변경을 읽는 현상
@Transactional(isolation = Isolation.READ_UNCOMMITTED) public void dirtyReadSimulation() { User user = userRepository.findById(1L).orElseThrow(); user.setBalance(user.getBalance() - 100); // 이 지점에서 다른 트랜잭션에서 사용자의 잔액을 읽을 수 있으며 더티 리드가 발생할 수 있습니다. }
- 반복 불가능 리드 (Non-repeatable Read)
- 트랜잭션 A가 같은 레코드를 두 번 읽고
- 그 사이에 트랜잭션 B 가 해당 레코드를 변경하고 커밋하는 현상
@Transactional(isolation = Isolation.READ_COMMITTED) public void nonRepeatableReadSimulation() { User user = userRepository.findById(1L).orElseThrow(); System.out.println("Initial Balance: " + user.getBalance()); // 이 지점에서 다른 트랜잭션에서 사용자의 잔액을 변경하고 커밋할 수 있습니다. User userAgain = userRepository.findById(1L).orElseThrow(); System.out.println("Balance after other transaction commits: " + userAgain.getBalance()); }
- 팬텀 리드 (Phantom Read)
- 트랜잭션 A가 특정 범위를 레코드를 읽고
- 그 사이에, 트랜잭션 B가 그 범위에 새로운 레코드를 추가하거나 제거하고 커밋하는 현상
@Transactional(isolation = Isolation.REPEATABLE_READ) public void phantomReadSimulation() { List<User> users = userRepository.findByBalanceGreaterThan(1000); System.out.println("Number of users with balance > 1000: " + users.size()); // 이 지점에서 다른 트랜잭션에서 잔액이 1000보다 큰 새 사용자를 추가하고 커밋할 수 있습니다. List<User> usersAgain = userRepository.findByBalanceGreaterThan(1000); System.out.println("Number of users with balance > 1000 after other transaction commits: " + usersAgain.size()); }
Uploaded by N2T