[좋아요 수 기준 HOT 게시판 이동 시 동시성 이슈 해결] 비관적 락을 이용한 게시글 좋아요 수 Race Condition 해결
·
프로젝트/Wedle
✨ 들어가며유저가 게시글에 좋아요를 누르면 일정 수치 이상일 때 'HOT 게시판'으로 이동시키는 기능을 구현했습니다. 이 기능은 좋아요 수가 많을수록 더 많은 유저들에게 노출되도록 유도하는 핵심적인 UX입니다.그런데 분명 좋아요 수가 3 이상인데도 HOT 게시판에 올라가지 않거나, 반대로 좋아요 수가 3 미만인데도 HOT 게시판에 남아있는 경우가 생겼습니다. 다수의 사용자가 동시에 좋아요를 누르거나 취소할 때 Race Condition이 발생했습니다.🧨 기존 코드의 문제점post.increaseLike();if (post.getLikeCount() >= 3) { moveToHotBoard(post);} post.decreaseLike();if (post.getLikeCount() 초기에는 좋아요 ..
[자주 조회되는 데이터 Redis 캐싱] – 학사 캘린더 캐싱
·
프로젝트/Wedle
✨ 들어가며우리는 매년 1년치 학교 일정을 Neis API를 통해 미리 받아와 DB에 저장해두고 있는데 실제로 사용자들이 가장 자주 조회하는 건 ‘오늘’ 혹은 ‘이번 달’ 일정이라서 자주 쓰는 정보를 매번 DB를 거치는 게 과연 효율적일까? 고민이 돼서 캐싱을 하기로 했습니다!💡 캐싱 고민의 시작초기에는 다음과 같은 방식으로 설계했습니다:매년 1월 1일, 1년치 데이터를 DB에 저장 사용자가 특정 날짜를 조회하면 DB에서 일정 조회DB에 없으면 외부 NEIS API를 호출해 저장 후 제공그런데,🤔 “같은 데이터를 왜 매번 DB에서 불러올까?”, “자주 조회되는 '이번 달' 일정만 Redis에 올려두면 더 빠르지 않을까?”라는 생각이 들어 Redis 캐싱을 도입하게 되었습니다.🚨 Redis 저장 중 ..
[JPA 성능 최적화] @ManyToOne(fetch = FetchType.LAZY) 와 Fetch Join 활용하기
·
프로젝트/Wedle
"JPA 성능 문제의 80%는 Fetch 전략으로 설명된다"는 말, 들어본 적 있나요?이번 글에서는 JPA의 연관 관계 중 @ManyToOne(fetch = FetchType.LAZY) 가 기본값일 때의 동작과, Fetch Join을 통해 어떻게 성능을 최적화하는지 작성해보겠습니다!🧩 @ManyToOne의 FetchType 기본값은?@ManyToOne@JoinColumn(name = "school_id", nullable = false)private School school;처음에는 이렇게 @ManyToOne만 선언해두었습니다.@ManyToOne의 기본 fetch 전략은 FetchType.EAGER입니다.👉🏻 위처럼 작성했을 경우 SchoolCalendar 엔티티를 조회할 때마다 School 엔티티..
[JPA 성능 최적화] 반복되는 save() 대신 saveAll()로 벌크 저장
·
프로젝트/Wedle
✨ 들어가며최근 진행 중인 프로젝트에서 학교 학사일정 데이터를 NEIS API에서 호출해 DB에 저장하는 기능을 만들고 있었습니다.처음엔 단순하게 for 루프 안에서 save()를 호출하는 방식으로 구현했는데요,데이터 양이 많아질수록 성능이 뚝뚝 떨어지는 현상이 생기기 시작했습니다.이 문제를 해결하기 위해 save() 대신 saveAll()을 사용해 벌크 저장 방식으로 리팩토링해봤습니다.이 글에서는 그 리팩토링 과정을 공유하려고 합니다!🧨 기존 코드의 문제점for (SchoolCalendarResponse response : calendarResponses.getSchoolCalendarResponses()) { for (EventDetailsResponse event : response.getE..