새로운 프로젝트를 시작하면서 주문시 재고감소 로직에 동시성 문제를 적용해 보았다.
리펙토링, 락 적용 전 코드
stockCheck에서 주문한 아이템수량을 상품 재고와 비교한다. 재고 수량보다 클 경우 예외를 던지고 이상없을 시 decrease하고 저장한다.
이 경우 동시에 100명이 주문할 경우 재고가 100감소가 되지 않는 문제가 발생한다
우선 pessimisticLock을 적용해보았다
테스트를 해보니 잘 적용된다.
그 다음은 RedissonLock을 적용해 보았다
레디스를 사용한 동시성 이슈는 계속 테스트가 실패했다.
그 이유는 orderService.placeOrder() 메소드 안에서 redissonLock을 사용했고 트랜잭션이 걸려있었기때문에 분산락 해제 시점과 트랜잭션 커밋 시점의 불일치로 재고감소에 문제가 있었다.
그래서 RedissonLockFacade 클래스를 따로 만들어 orderService.placeOrder()를 호출했다
RedissonLock 테스트도 성공했다.
두가지중 어느것이 더 좋을까 Jmeter로 테스트 해봤다.
300명이 동시 주문할 경우
문제발생
코드를 잘못짰고 수정중에 redissonLock 오류 발견
redissonlock경우 차감이랑 저장이 다른 트랜잭션 안에서 실행된다. 그래서 뒤에 있는 메소드가 실패해도 앞 메소드는 롤백안되고 그대로 커밋 된다.
문제해결
재고 감소 -> 주문 저장 , 실패시 재고 증가시키는 로직 구현했다
try catch 사용해서 예외발생시 increase로직을 구현하면 되는 단순한 문제였는데
decrease를 롤백시키는 기능을 계속 찾거나 순서를 바꾸면서 다른 방법을 계속 찾았다.
마지막에 코드 리펙토링을 하면서 Pessimistic 락을 사용하기로 결정했다.
그 이유는 Redis에 대한 이해도가 조금 부족했다고 느껴 이번 프로젝트에는 조금 더 간단하다고 느낀 Pessimistic 락을 사용했다.
한 트랜잭션 안에서 사용이 가능해 편리하고 성능차이에도 큰 문제가 없었다.
'이슈' 카테고리의 다른 글
RDB vs Elasticsearch 검색 성능 비교 (0) | 2025.01.10 |
---|---|
Kafka, Redis를 활용한 이벤트 중복 처리 방지 (2) | 2024.12.19 |
[Jenkins] 용량 부족 - EBS 볼륨 연결 (0) | 2024.11.19 |
AWS EC2 배포 작업 (0) | 2023.09.07 |
데이터 설계에 대한 고민 (0) | 2023.07.28 |