Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] 데이터 정합성을 맞추는 스케줄러 작성 #789

Merged
merged 3 commits into from
Oct 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.woowacourse.f12.application.batch;

import com.woowacourse.f12.domain.member.MemberRepository;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
public class BatchService {

private final MemberRepository memberRepository;

public BatchService(final MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}

@Transactional
public void updateFollowerCount() {
memberRepository.updateFollowerCountBatch();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.woowacourse.f12.application.batch;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;

@Slf4j
public class FollowerCountBatchScheduler {

private static final String LOG_FORMAT = "Class : {}, Message : {}";

private final BatchService batchService;

public FollowerCountBatchScheduler(final BatchService batchService) {
this.batchService = batchService;
}

@Scheduled(cron = "0 0 0/1 1/1 * ? *")
public void execute() {
try {
batchService.updateFollowerCount();
} catch (Exception e) {
log.error(LOG_FORMAT, e.getClass().getSimpleName(), e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ public void update(final Long reviewId, final Long memberId, final ReviewRequest
final Review updateReview = updateRequest.toReview(target.getProduct(), target.getMember());
int ratingGap = updateReview.getRating() - target.getRating();
target.update(updateReview);
reviewRepository.flush();
productRepository.updateProductStatisticsForReviewUpdate(target.getProduct().getId(), ratingGap);
}

Expand All @@ -125,8 +124,6 @@ public void delete(final Long reviewId, final Long memberId) {
.orElseThrow(InventoryProductNotFoundException::new);
inventoryProductRepository.delete(inventoryProduct);
reviewRepository.delete(review);
// inventoryProductRepository.flush();
reviewRepository.flush();
productRepository.updateProductStatisticsForReviewDelete(review.getProduct().getId(), review.getRating());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.woowacourse.f12.config;

import com.woowacourse.f12.application.batch.BatchService;
import com.woowacourse.f12.application.batch.FollowerCountBatchScheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
@Configuration
public class SchedulerConfig {

private final BatchService batchService;

public SchedulerConfig(final BatchService batchService) {
this.batchService = batchService;
}

@Bean(name = "followerCountBatchScheduler")
public FollowerCountBatchScheduler followerCountBatchScheduler() {
return new FollowerCountBatchScheduler(batchService);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@

import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom {

Optional<Member> findByGitHubId(String gitHubId);

@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query(value = "update Member m set m.followerCount = (select count(f) from Following f where f.followingId = m.id)")
void updateFollowerCountBatch();
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ public interface ProductRepository extends JpaRepository<Product, Long>, Product

List<Product> findByReviewCountGreaterThanEqualAndRatingGreaterThanEqual(int reviewCount, double rating);

@Modifying(clearAutomatically = true)
@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query(value = "update Product p "
+ "set p.rating = (p.totalRating + :reviewRating) / cast((p.reviewCount + 1) as double), "
+ "p.reviewCount = p.reviewCount + 1, "
+ "p.totalRating = p.totalRating + :reviewRating "
+ "where p.id = :productId")
void updateProductStatisticsForReviewInsert(Long productId, int reviewRating);

@Modifying(clearAutomatically = true)
@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query(value = "update Product p "
+ "set p.rating = case p.reviewCount when 1 then 0 "
+ "else ((p.totalRating - :reviewRating) / cast((p.reviewCount - 1) as double)) end , "
Expand All @@ -26,7 +26,7 @@ public interface ProductRepository extends JpaRepository<Product, Long>, Product
+ "where p.id = :productId")
void updateProductStatisticsForReviewDelete(Long productId, int reviewRating);

@Modifying(clearAutomatically = true)
@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query(value = "update Product p "
+ "set p.rating = (p.totalRating + :ratingGap) / cast(p.reviewCount as double), "
+ "p.totalRating = p.totalRating + :ratingGap "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,27 @@ class MemberRepositoryTest {
assertThatThrownBy(() -> memberRepository.save(member2))
.isInstanceOf(DataIntegrityViolationException.class);
}

@Test
void 회원의_팔로워_수의_정합성을_맞춘다() {
// given
Member member = CORINNE.생성();
Member follower = MINCHO.생성();
memberRepository.save(member);
memberRepository.save(follower);
Following following = Following.builder()
.followerId(follower.getId())
.followingId(member.getId())
.build();
followingRepository.save(following);

// when
memberRepository.updateFollowerCountBatch();

// then
Member actual = memberRepository.findById(member.getId())
.orElseThrow();

assertThat(actual.getFollowerCount()).isOne();
}
}