• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

Spring Data Redis 관련 질문

22.08.22 11:41 작성 조회수 238

0

안녕하세요 강의 잘 보고 있습니다.

현재 RedisTemplate이용해서 프로젝트를 진행중인데 궁금한점이 생겨 질문 드립니다

 

RedisTemplate의 Watch() 메소드는 낙관적 락 기반으로 동작하며

1번의 exec() 혹은 외부 트랜잭션에서의 변경만 허용하는 것으로 알고 있습니다.

만약 Watch()로 감시중이었던 Redis의 Key에서 추가적인 변경이 일어나면 변경되지 않는 것으로 알고있구요

 

그러면 이것 역시도 낙관적 락 기반 동작이기 때문에 실패 시 Retry관련 로직을 구현해줘야 하는 부분일까요??

제 생각은 추가적인 변경 시 진행중이던 로직이 취소되기 때문에 Retry를 해줘야 할 것 같은데

RedisTemplate의 watch를 사용한 여러 깃헙 프로젝트를 찾아봐도 retry관련부분을 구현한걸 찾기가 힘들어 질문드립니다

 

감사합니다

답변 1

답변을 작성해보세요.

0

skehdxhd 님 안녕하세요!

혹시 구체적인 사례를 들어주실 수 있으실까요 ?

watch 를 어떤식으로 사용하시는지 유추하기가 어렵습니다.

github 을 통해 소스를 공유해주시면 감사하겠습니다.

skehdxhd님의 프로필

skehdxhd

질문자

2022.08.23

github이 private로 되어있어서.. 설명으로 대체하겠습니다

쇼핑몰의 재고 처리 관련 로직을 레디스로 처리하려고 하는데

예를 들어 같은 상품의 주문 2개가 거의 동시에 일어나는 경우입니다

자세하게 설명하면 10개의 재고가 있었고 각 주문이 1개의 수량을 주문한다고 가정할 때,

먼저 도착한 주문 요청이 재고를 9개로 감소시키기 전에 또 다른 주문 요청이 들어오는 경우입니다

 

이럴때는 락을 걸어서 데이터의 정합성을 보장해줘야한다고 생각했고,

Watch로 락을 걸 경우 다른 주문은 로직이 진행되지 않기 떄문에 Retry를 구현해주는게 맞지 않나 생각했습니다

안녕하세요 skehdxhd 님

첫째로 데이터의 정합성을 보장해줘야 하는것은 맞습니다.

둘째로 watch 가 낙관적 락 방식이라면 비즈니스 로직에 따라 다르겠지만 retry 를 해줘야 하는것이 맞을듯합니다.

셋째로 retry 방식은 룰을 정해서 하면 될듯 합니다.

예를들어 "3번만 재시도한다" 라는 룰이 있다면 아래와 같이 구현할 수 있을듯합니다.

int retryCount = 0;

while (retryCount < 3) {
    try {
         getLock();
         // 로직
         break;
    } catch(Exception e) {
         // 로깅
         retryCount++;
    } finally {
         releaseLock();
    }
}

제가 watch 를 사용해보지 않았기도하고 skehdxhd 님께서 어떤방식으로 구현하고자 하는지 모르기때문에 답변에 한계가 있을듯합니다.

lock 은 일반적으로 watch 를 활용하기보다는 setnx 또는 reddisson 에서 제공해주는 Lock 을 많이 사용하는 편이기는 합니다.

추가적인 질문이 있으시다면 댓글 부탁드리겠습니다!

skehdxhd님의 프로필

skehdxhd

질문자

2022.08.25

많은 공부가 되었습니다. 감사합니다!