-
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.
* [fix] : dev 브랜치와의 충돌 해결 * [refactor] : 불필요한 로직 제거 * [feat] : redisson 설정 추가 * [feat] : 분산락 어노테이션 구현 * [feat] : 분산락 AOP 관련 트랜잭션 설정 및 key 파싱 클래스 추가 * [feat] : 입찰 등록 로직에 분산락 어노테이션 적용 * [test] : 동시성 테스트 로직 추가 * [test] : ObjectProvider 사용에 따른 입찰 등록 테스트 수정 * [feat] : 기본 생성자 private 설정 * [feat] : 대기 시간 동안 획득하지 못할 시 예외 반환 * [feat] : 동시성 제어 로직 수정 * [test] : 동시성 제어 로직 수정 반영 * [test] : 불필요한 코드 제거 * [refactor] : BiddingMapper 파라미터 수정 * [refactor] : 입찰자 검증 로직 생성자로 이동 * [feat] : 등록 메서드 내에서 호출하던 별도의 동시성 제어 메서드 삭제 후 통합 * [test] : 등록 메서드 내에서 호출하던 별도의 동시성 제어 메서드 삭제 후 통합 반영 * [test] : 동시성 테스트 리팩토링 * [style] : 코드 리포멧팅
- Loading branch information
Showing
15 changed files
with
310 additions
and
50 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
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
26 changes: 26 additions & 0 deletions
26
core/src/main/java/dev/handsup/common/config/RedissonConfig.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,26 @@ | ||
package dev.handsup.common.config; | ||
|
||
import org.redisson.Redisson; | ||
import org.redisson.api.RedissonClient; | ||
import org.redisson.config.Config; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
public class RedissonConfig { | ||
private static final String REDISSON_HOST_PREFIX = "redis://"; | ||
@Value("${spring.data.redis.host}") | ||
private String host; | ||
@Value("${spring.data.redis.port}") | ||
private int port; | ||
|
||
@Bean | ||
public RedissonClient redissonClient() { | ||
RedissonClient redisson = null; | ||
Config config = new Config(); | ||
config.useSingleServer().setAddress(REDISSON_HOST_PREFIX + host + ":" + port); | ||
redisson = Redisson.create(config); | ||
return redisson; | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
core/src/main/java/dev/handsup/common/redisson/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 dev.handsup.common.redisson; | ||
|
||
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(); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
core/src/main/java/dev/handsup/common/redisson/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,23 @@ | ||
package dev.handsup.common.redisson; | ||
|
||
import org.springframework.expression.ExpressionParser; | ||
import org.springframework.expression.spel.standard.SpelExpressionParser; | ||
import org.springframework.expression.spel.support.StandardEvaluationContext; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.NoArgsConstructor; | ||
|
||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
public class CustomSpringELParser { | ||
|
||
public static Object getDynamicValue(String[] parameterNames, Object[] args, String key) { | ||
ExpressionParser parser = new SpelExpressionParser(); | ||
StandardEvaluationContext context = new StandardEvaluationContext(); | ||
|
||
for (int i = 0; i < parameterNames.length; i++) { | ||
context.setVariable(parameterNames[i], args[i]); | ||
} | ||
|
||
return parser.parseExpression(key).getValue(context, Object.class); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
core/src/main/java/dev/handsup/common/redisson/DistributeLock.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 dev.handsup.common.redisson; | ||
|
||
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; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ElementType.TYPE, ElementType.METHOD}) | ||
public @interface DistributeLock { | ||
|
||
String key(); // 락 이름 | ||
|
||
TimeUnit timeUnit() default TimeUnit.SECONDS; // 시간 단위 | ||
|
||
long waitTime() default 5L; // 대기 시간 | ||
|
||
long leaseTime() default 3L; // 임대 시간 | ||
} |
63 changes: 63 additions & 0 deletions
63
core/src/main/java/dev/handsup/common/redisson/DistributeLockAop.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,63 @@ | ||
package dev.handsup.common.redisson; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
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 dev.handsup.common.exception.ValidationException; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Aspect | ||
@Component | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class DistributeLockAop { | ||
|
||
private static final String REDISSON_KEY_PREFIX = "RLOCK_"; | ||
private final RedissonClient redissonClient; | ||
private final AopForTransaction aopForTransaction; | ||
|
||
@Around("@annotation(dev.handsup.common.redisson.DistributeLock)") | ||
public Object concurrencyLock(final ProceedingJoinPoint joinPoint) throws Throwable { | ||
|
||
MethodSignature signature = (MethodSignature)joinPoint.getSignature(); | ||
Method method = signature.getMethod(); | ||
DistributeLock annotation = method.getAnnotation(DistributeLock.class); | ||
|
||
final long waitTime = annotation.waitTime(); | ||
final long leaseTime = annotation.leaseTime(); | ||
final TimeUnit unit = annotation.timeUnit(); | ||
final String lockName = annotation.key(); | ||
|
||
String key = REDISSON_KEY_PREFIX + CustomSpringELParser.getDynamicValue(signature.getParameterNames(), | ||
joinPoint.getArgs(), lockName); | ||
RLock rLock = redissonClient.getLock(key); | ||
|
||
try { | ||
boolean hasLock = rLock.tryLock(waitTime, leaseTime, unit); | ||
|
||
if (!hasLock) { | ||
throw new ValidationException(LockErrorCode.FAILED_TO_GET_LOCK); | ||
} | ||
|
||
log.info("get lock success {}", key); | ||
// 실제 수행 로직 | ||
return aopForTransaction.proceed(joinPoint); | ||
|
||
} catch (InterruptedException e) { | ||
Thread.currentThread().interrupt(); | ||
log.info("get lock fail {}", key); | ||
throw new InterruptedException(); | ||
} finally { | ||
rLock.unlock(); | ||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
core/src/main/java/dev/handsup/common/redisson/LockErrorCode.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 dev.handsup.common.redisson; | ||
|
||
import dev.handsup.common.exception.ErrorCode; | ||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public enum LockErrorCode implements ErrorCode { | ||
|
||
FAILED_TO_GET_LOCK("주어진 시간 동안 락을 획득하는데 실패했습니다.", "rl_001"); | ||
|
||
private final String message; | ||
private final String code; | ||
} |
Oops, something went wrong.