동시성 문제를 해결하는 다양한 방법
Java 사용하는 방법
- Synchronized를 활용한 방법
@Service
@RequiredArgsConstructor
public class StockService {
private final StockRepository stockRepository;
public synchronized void decrease(Long id, Long quantity) {
Stock stock = stockRepository.findById(id).orElseThrow();
stock.decrease(quantity);
stockRepository.saveAndFlush(stock);
}
- 자바에서 지원하는, synchronized를 사용하면 접근하고 있는 메서드에 하나의 스레드만 접근할 수 있도록 작동
- 현재 데이터를 사용하고 있는 해당 스레드를 제외하고 나머지 스레드들은 데이터 접근을 막아 순차적으로 데이터에 접근할 수 있도록 해줌
간단하게 메서드에 synchronized 키워드를 추가하고, @Transactional을 제거함으로써 동시성 문제를 해결할 수 있다.
Transactioanal을 제거하는 이유는 트랜잭션 관리 방식은 기본적으로 프록시 방식으로 AOP가 적용되기 때문.
트랜잭션 프록시가 트랜잭션 처리 로직을 수행할 때 새로운 클래스를 만들어 Logic을 실행하게 된다.
synchronized를 통해 한 개의 스레드만 접근할 수 있게 막더라도 트랜잭션에 의해 새로운 프록시로 수행하게 되어버리면 프록시 로직은 synchronized가 걸린 상태가 아니기 때문에 원하는 결과를 얻지 못함
- 문제점
- Synchronized는 하나의 프로세스 안에서만 보장이 된다
- 즉, 서버가 1대일 때는 문제가 없지만 서버가 여러 대 일경우 인스턴스가 여러 개 존재하는 것이기에, 실질적인 운영 환경에서는 데이터의 정합성을 보장할 수 없음
DB 사용하는 방법
- Pessimistic Lock (비관적 락)
- 트랜잭션이 시작될 때 Shared Lock 또는 Exclusice Lock을 걸고 시작하는 방법
- Shared Lock을 걸게 되면 write를 하기 위해서는 Exclucive Lock을 얻어야하는데 Shared Lock이 다른 트랜잭션에 의해 걸려있으면 해당 Lock을 얻지 못해 업데이트를 할 수 없음
- 수정하기 위해서는 해당 트랜잭션을 제외한 모든 트랜잭션이 종료(commit) 되어야한다.
- Optimistic Lock (낙관적 락)
- Optimistic Lock은 수정할 때 먼저 이 값을 수정했다고 명시하여 다른 사람이 동일한 조건으로 값을 수정할 수 없게 하는 것.
- 낙관적 락은 DB에서 제공해주는 특징을 이용하는 것이 아닌 Application Level에서 잡아주는 Lock
- 낙관적 락은 별도의 version 구분 컬럼을 추가하여 충돌적인 업데이트를 막아줌
- version 뿐만 아니라 hashcode 또는 timestamp를 사용하기도 한다.
- Rollback (롤백)
- 업데이트를 하는 테이블이 1개가 아니라 2개의 테이블이며 2번째 테이블을 업데이트하다 이와같은 충돌이 발생했다면 하나의 수정 요청에 대해서는 롤백이 필요
- 비관적 락은 하나의 트랜잭션으로 묶여있기 때문에 수정이 하나 실패하면 DB 단에서 전체 Rollback이 발생
- 만약 실패시에는 Transaction이 실패한 것이기에 트랜잭션 전체에 자동으로 rollback 발생
- 낙관적 락은 트랜잭션을 사용하지 않기에 충돌이 발생하여 수정을 못한 부분이 있으면 롤백에 대한 책임을 Application 단에서 가지고 Application에서 수동으로 롤백을 해줘야 한다.
- 비관적 락 vs 낙관적 락
- 성능적으로는 비관적 락이 더 좋다.
- 낙관적 락은 트랜잭션이 필요하지 않다.
- 낙관적 락의 최대 단점 = 롤백이다. => 충돌 발생 시 개발자가 수동으로 롤백을 하나하나 처리해줘야 한다.
- 비관적 락은 트랜잭션을 롤백하면 끝남
- 따라서, 낙관적 락은 충돌이 많이 예상되거나 충돌이 발생했을 때 비용이 많이 들것이라고 판단되는 곳에서는 사용하지 않는 것이 좋아보임
728x90
'ssung_항해일지 > 항해99_실전 프로젝트' 카테고리의 다른 글
실전 프로젝트 - 35일차 (0) | 2023.04.15 |
---|---|
실전 프로젝트 - 34일차 (0) | 2023.04.13 |
실전 프로젝트 - 27일차 (0) | 2023.04.06 |
실전 프로젝트 - 25일차 (0) | 2023.04.04 |
실전 프로젝트 - 24일차 (0) | 2023.04.04 |