From 9d7f3a87818faaddc8257e2464959ebc7f08aafd Mon Sep 17 00:00:00 2001 From: sohyundoh Date: Wed, 13 Nov 2024 21:54:44 +0900 Subject: [PATCH] =?UTF-8?q?#575=20[feat]=20DistributedLock=20=ED=85=9C?= =?UTF-8?q?=ED=94=8C=EB=A6=BF=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20=ED=99=9C?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mile/common/lock/DistributedLock.java | 36 +++++++++++++++++++ .../lock/MoimNameRequestAspect.java | 23 ++++-------- .../com/mile/moim/service/MoimRetriever.java | 2 +- .../popular/MoimPopularInfoRegister.java | 11 ++++-- .../popular/MoimPopularInfoService.java | 2 -- 5 files changed, 52 insertions(+), 22 deletions(-) create mode 100644 module-domain/src/main/java/com/mile/common/lock/DistributedLock.java rename module-domain/src/main/java/com/mile/{moim/service => common}/lock/MoimNameRequestAspect.java (54%) diff --git a/module-domain/src/main/java/com/mile/common/lock/DistributedLock.java b/module-domain/src/main/java/com/mile/common/lock/DistributedLock.java new file mode 100644 index 00000000..5415b3f8 --- /dev/null +++ b/module-domain/src/main/java/com/mile/common/lock/DistributedLock.java @@ -0,0 +1,36 @@ +package com.mile.common.lock; + +import com.mile.exception.message.ErrorMessage; +import com.mile.exception.model.MileException; +import lombok.RequiredArgsConstructor; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +@RequiredArgsConstructor +@Component +public class DistributedLock { + + private final RedissonClient redissonClient; + + public void getLock(final String key) { + final RLock lock = redissonClient.getLock(key); + try { + checkAvailability(lock.tryLock(3, 4, TimeUnit.SECONDS)); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + public void afterLock(final String key) { + final RLock lock = redissonClient.getLock(key); + lock.unlock(); + } + + public void checkAvailability(final Boolean available) { + if (!available) throw new MileException(ErrorMessage.TIME_OUT_EXCEPTION); + } + +} diff --git a/module-domain/src/main/java/com/mile/moim/service/lock/MoimNameRequestAspect.java b/module-domain/src/main/java/com/mile/common/lock/MoimNameRequestAspect.java similarity index 54% rename from module-domain/src/main/java/com/mile/moim/service/lock/MoimNameRequestAspect.java rename to module-domain/src/main/java/com/mile/common/lock/MoimNameRequestAspect.java index 719b6ed6..7c45c128 100644 --- a/module-domain/src/main/java/com/mile/moim/service/lock/MoimNameRequestAspect.java +++ b/module-domain/src/main/java/com/mile/common/lock/MoimNameRequestAspect.java @@ -1,46 +1,35 @@ -package com.mile.moim.service.lock; +package com.mile.common.lock; -import com.mile.exception.message.ErrorMessage; -import com.mile.exception.model.MileException; import lombok.RequiredArgsConstructor; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; -import org.redisson.api.RLock; -import org.redisson.api.RedissonClient; import org.springframework.stereotype.Component; -import java.util.concurrent.TimeUnit; - @Aspect @RequiredArgsConstructor @Component public class MoimNameRequestAspect { - private final RedissonClient redissonClient; - private final static String MOIM_NAME_LOCK = "MOIM_NAME_LOCK : "; + private final DistributedLock distributedLock; + private final static String MOIM_NAME_LOCK = "MOIM_NAME_LOCK"; private final AopForTransaction aopForTransaction; - @Pointcut("@annotation(com.mile.moim.service.lock.AtomicValidateUniqueMoimName)") + @Pointcut("@annotation(com.mile.common.lock.AtomicValidateUniqueMoimName)") public void uniqueMoimNameCut() { } @Around("uniqueMoimNameCut()") public Object validateUniqueName(final ProceedingJoinPoint joinPoint) throws Throwable { - final RLock lock = redissonClient.getLock(MOIM_NAME_LOCK); try { - checkAvailability(lock.tryLock(3, 4, TimeUnit.SECONDS)); + distributedLock.getLock(MOIM_NAME_LOCK); return aopForTransaction.proceed(joinPoint); } catch (InterruptedException e) { throw new RuntimeException(e); } finally { - lock.unlock(); + distributedLock.afterLock(MOIM_NAME_LOCK); } } - public void checkAvailability(final Boolean available) { - if (!available) throw new MileException(ErrorMessage.TIME_OUT_EXCEPTION); - } - } diff --git a/module-domain/src/main/java/com/mile/moim/service/MoimRetriever.java b/module-domain/src/main/java/com/mile/moim/service/MoimRetriever.java index f5b3be0f..f3da8cd1 100644 --- a/module-domain/src/main/java/com/mile/moim/service/MoimRetriever.java +++ b/module-domain/src/main/java/com/mile/moim/service/MoimRetriever.java @@ -6,7 +6,7 @@ import com.mile.moim.domain.Moim; import com.mile.moim.repository.MoimRepository; import com.mile.moim.service.dto.response.MoimInfoResponse; -import com.mile.moim.service.lock.AtomicValidateUniqueMoimName; +import com.mile.common.lock.AtomicValidateUniqueMoimName; import com.mile.user.domain.User; import com.mile.common.utils.DateUtil; import com.mile.writername.domain.WriterName; diff --git a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java index c2a18ac0..93f447ad 100644 --- a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java +++ b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java @@ -1,5 +1,6 @@ package com.mile.moim.service.popular; +import com.mile.common.lock.DistributedLock; import com.mile.curious.repository.dto.PostAndCuriousCountInLastWeek; import com.mile.curious.service.CuriousRetriever; import com.mile.moim.domain.Moim; @@ -7,7 +8,6 @@ import com.mile.moim.domain.popular.MoimCuriousWriter; import com.mile.moim.domain.popular.MoimPopularInfo; import com.mile.moim.repository.MoimPopularInfoRepository; -import com.mile.moim.service.lock.AtomicMoimPopulerInfo; import com.mile.writername.domain.WriterName; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.CachePut; @@ -25,6 +25,7 @@ public class MoimPopularInfoRegister { private final MoimPopularInfoRepository moimPopularInfoRepository; private final CuriousRetriever curiousRetriever; + private final DistributedLock distributedLock; private Set getMoimCuriousPost(final List mostCuriousPostsInLastWeek) { @@ -46,6 +47,8 @@ private Set getMoimCuriousWriter(final List mostCuriousPostsInLastWeek = curiousRetriever.findMostCuriousPostsInLastWeek(moim); Set moimCuriousPosts = getMoimCuriousPost(mostCuriousPostsInLastWeek); @@ -54,7 +57,11 @@ public MoimPopularInfo setMostPopularInfoOfMoim(final Moim moim) { MoimPopularInfo moimPopularInfo = MoimPopularInfo.of(moim.getId(), moimCuriousPosts, moimCuriousWriters); - return moimPopularInfoRepository.saveAndFlush(moimPopularInfo); + moimPopularInfoRepository.saveAndFlush(moimPopularInfo); + + distributedLock.afterLock("MOIM_POPULAR_LOCK"); + + return moimPopularInfo; } } diff --git a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java index 90943c76..648775ea 100644 --- a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java +++ b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java @@ -4,7 +4,6 @@ import com.mile.moim.domain.Moim; import com.mile.moim.domain.popular.MoimPopularInfo; import com.mile.moim.repository.MoimPopularInfoRepository; -import com.mile.moim.service.lock.AtomicMoimPopulerInfo; import com.mile.slack.module.SendMessageModule; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; @@ -22,7 +21,6 @@ public class MoimPopularInfoService { @Cacheable(value = "moimPopularInfo", key = "#moim.id") - @AtomicMoimPopulerInfo public MoimPopularInfo getMoimPopularInfo(final Moim moim) { return moimPopularInfoRepository.findByMoimId(moim.getId()).orElseGet( () -> moimPopularInfoRegister.setMostPopularInfoOfMoim(moim)