-
8월 24일 목요일 TIL 회고록카테고리 없음 2023. 8. 25. 02:15
조회수 구현을 위해..
레디스를 사용해서 게시글 상세 조회, 수정, 삭제시 캐시를 생성하고, 수정하고, 삭제하는 기능을 만들었었는데..
생각해보니까 게시글 상세 조회 전체를 캐시로 만들어버리면 문제가 있다는 것을 깨달았다.
같은 게시글을 조회하는 유저 A, 유저 B가 있다고 할 때, 유저 A가 게시글 상세 조회를 하여 캐시가 1분동안 남아있다고 할 때
유저 B가 그 게시글을 상세 조회를 하면?? 레디스에는 아직 캐시가 남아있어서 조회수가 올라가지 않는다.
좋아요도 마찬가지다. 유저가 좋아요를 누르면? 아직 레디스에는 좋아요가 0인 캐시가 남아있어 캐시가 남아있는 동안에는 좋아요가 올라가지 않는다. 이런 문제가 있기에 게시글 상세 조회에 캐시를 생성하지 않기로 일단 결정하였다.
그래서 조회수만 캐시를 사용해서 적용해보기로 했다. 유저 닉네임을 Value 값으로 저장해 레디스에 유저 닉네임이 있다면, 조회수 카운트가 올라가지 않고 레디스에 유저 닉네임이 없으면 조회수 카운트가 올라가도록 만들어보려했다.
String redisKey = basicBoardId.toString(); redisDao.setValues(redisKey, Integer.toString(views)); String redisUserKey = user.getUsername(); String values = redisDao.getValues(redisKey); views = Integer.parseInt(values); // 유저를 Key로 조회한 게시글 ID List안에 해당 게시글 ID가 포함되어있지 않는다면, if (!redisDao.getValuesList(redisUserKey).contains(redisKey)) { redisDao.setValuesList(redisUserKey, redisKey); views = Integer.parseInt(values) + 1; redisDao.setValues(redisKey, String.valueOf(views)); }
1. boardId.toString() 한 값을 redisKey에 넣었다.
2. redisDao 클래스에 setValues 메서드를 사용해서 redisKey 키 값에 views를 toString 한 값을 넣었다.
3. 유저의 닉네임을 redisUserKey에 넣었다.
4. redisDao 클래스에 getValues 메서드를 사용해서 redisKey 키의 Value 값을 values에 넣었다.
5. Interger,parseInt(values) 한 값을 views에 넣었다.
6. 유저를 Key로 조회한 게시글 ID List 안에 해당 게시글 ID가 포함되어있지 않는다면,
7. redisDao 클래스에 setValuesList 메서드를 사용해 유저 Key로 해당 글 ID를 List 형태로 저장한다.
8. Integer.parseInt(values)에 1을 더해준 값을 views에 넣는다. (조회수 증가)
9. redisDao 클래스에 setValues 메서드를 사용해 글 ID Key로 조회수를 저장한다.
참고한 블로그에서는 2번 setValues 메서드를 사용하지 않았다. (어떻게 했지..)
setValues를 해주지 않으면 4번 String values가 null이 나온다.
처음에 이 오류가 나와서 코드를 리팩토링 해보았지만 계속 null이 나와서 생각해 본 결과 나는 redisKey란 키 값만 선언했지 Value를 선언하지 않았다. 그래서 redisDao.getValues로 Value 값을 가져오고 그 값을 views에 넣는건데 Value 값을 선언하지 않아서 계속 null이 나오는 것 같았다. 그래서 내가 임의로 setValues 메서드를 사용해서 값을 넣었더니 오류가 해결되고 레디스에서도 잘 들어가긴 하는데..
어떻게 가져와야 할지 모르겠다. 저번에 조회수를 구현하기 위해 Repository단에 쿼리문을 사용해서 만든 메서드가 있는데..
@Modifying(clearAutomatically = true, flushAutomatically = true) @Query("UPDATE Board b SET b.views = b.views + 1 WHERE b.id = :id") int updateView(@Param("id") Long id)
이 메서드를 사용해서 게시글 선택 조회를 하면 레디스에서는 1이 저장되고, 선택 조회에서는 조회수가 1이 출력되지만 게시글 전체 조회에서 출력되는 조회수는 중복 조회가 되서 같은 유저가 여러번 조회해도 조회수가 올라간다. 그래서 일단 보류..
이번에는 countByViews 메서드를 사용해서 해보았다.
int countByViews(Long boardId);
이것도 문제가 있어서 보류.. (조회수가 안올라간다.)
redisKey의 Value값을 어떻게 넣어야할지.. 계속 생각해봐야겠다.