-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/main' into feature/143_june-777-…
…kimhyun5u_음식-상품-재고-캐싱 # Conflicts: # build.gradle # src/main/java/camp/woowak/lab/infra/config/RedissonConfiguration.java # src/main/resources/application.yaml # src/test/resources/application.yml
- Loading branch information
Showing
13 changed files
with
432 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
src/main/java/camp/woowak/lab/infra/aop/AopForTransaction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package camp.woowak.lab.infra.aop; | ||
|
||
import org.aspectj.lang.ProceedingJoinPoint; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.transaction.annotation.Propagation; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Component | ||
public class AopForTransaction { | ||
|
||
@Transactional(propagation = Propagation.REQUIRES_NEW) | ||
public Object proceed(final ProceedingJoinPoint joinPoint) throws Throwable { | ||
return joinPoint.proceed(); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/camp/woowak/lab/infra/aop/CustomSpringELParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package camp.woowak.lab.infra.aop; | ||
|
||
import org.springframework.expression.spel.standard.SpelExpressionParser; | ||
import org.springframework.expression.spel.support.StandardEvaluationContext; | ||
|
||
public class CustomSpringELParser { | ||
private CustomSpringELParser() { | ||
} | ||
|
||
public static Object getDynamicValue(String[] parameterNames, Object[] args, String key) { | ||
SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); | ||
StandardEvaluationContext context = new StandardEvaluationContext(); | ||
|
||
for (int parmeterIdx = 0; parmeterIdx < parameterNames.length; parmeterIdx++) { | ||
context.setVariable(parameterNames[parmeterIdx], args[parmeterIdx]); | ||
} | ||
|
||
return spelExpressionParser.parseExpression(key).getValue(context, Object.class); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/main/java/camp/woowak/lab/infra/aop/DistributedLock.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package camp.woowak.lab.infra.aop; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
@Target(ElementType.METHOD) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface DistributedLock { | ||
|
||
/** | ||
* @return 분산락의 키 이름 | ||
*/ | ||
String key(); | ||
|
||
/** | ||
* @return 분산락 단위 시간 | ||
*/ | ||
TimeUnit timeUnit() default TimeUnit.SECONDS; | ||
|
||
/** | ||
* @return 분산락 대기 시간 | ||
*/ | ||
long waitTime() default 5L; | ||
|
||
/** | ||
* @return 분산락을 점유한 스레드가 정해진 시간이 지나면 락을 해제 | ||
*/ | ||
long leaseTime() default 5L; | ||
|
||
} |
65 changes: 65 additions & 0 deletions
65
src/main/java/camp/woowak/lab/infra/aop/DistributedLockAop.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package camp.woowak.lab.infra.aop; | ||
|
||
import java.lang.reflect.Method; | ||
|
||
import org.aspectj.lang.ProceedingJoinPoint; | ||
import org.aspectj.lang.annotation.Around; | ||
import org.aspectj.lang.annotation.Aspect; | ||
import org.aspectj.lang.reflect.MethodSignature; | ||
import org.redisson.api.RLock; | ||
import org.redisson.api.RedissonClient; | ||
import org.springframework.stereotype.Component; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Aspect | ||
@Component | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class DistributedLockAop { | ||
|
||
private static final String REDISSON_LOCK_PREFIX = "LOCK:"; | ||
private final RedissonClient redissonClient; | ||
private final AopForTransaction aopForTransaction; | ||
|
||
@Around("@annotation(camp.woowak.lab.infra.aop.DistributedLock)") | ||
public Object around(ProceedingJoinPoint joinPoint) throws Throwable { | ||
MethodSignature signature = (MethodSignature)joinPoint.getSignature(); | ||
Method method = signature.getMethod(); | ||
DistributedLock distributedLock = method.getAnnotation(DistributedLock.class); | ||
|
||
String key = REDISSON_LOCK_PREFIX + CustomSpringELParser.getDynamicValue(signature.getParameterNames(), | ||
joinPoint.getArgs(), | ||
distributedLock.key()); | ||
RLock rLock = redissonClient.getLock(key); | ||
|
||
try { | ||
boolean locked = rLock.tryLock(distributedLock.waitTime(), distributedLock.leaseTime(), | ||
distributedLock.timeUnit()); | ||
if (!locked) { | ||
log.warn("Failed to acquire lock for method {} with key {}", method.getName(), key); | ||
throw new IllegalStateException("Unable to acquire lock"); | ||
} | ||
log.info("Acquired lock for method {} with key {}", method.getName(), key); | ||
return aopForTransaction.proceed(joinPoint); | ||
} catch (InterruptedException e) { // rLock.tryLock | ||
log.warn("Interrupted while trying to acquire lock for method {} with key {}", method.getName(), key); | ||
throw e; | ||
} finally { | ||
releaseLock(rLock, method, key); | ||
} | ||
} | ||
|
||
private void releaseLock(RLock rLock, Method method, String key) { | ||
try { | ||
if (rLock.isHeldByCurrentThread()) { | ||
rLock.unlock(); | ||
log.info("Released lock for method {} with key {}", method.getName(), key); | ||
} | ||
} catch (IllegalMonitorStateException e) { | ||
log.warn("Failed to release lock for method {} with key {}", method.getName(), key, e); | ||
throw e; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.