Skip to content

Commit

Permalink
feat : 동시성 문제 해결 비관적락에서 분산락으로 변경
Browse files Browse the repository at this point in the history
- Redis & Redisson 적용
- 분산락 aop로 적용
- 통합테스트 변경
  • Loading branch information
rlatmd0829 committed Apr 29, 2024
1 parent 4a0bcc2 commit 0e8acf5
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 4 deletions.
1 change: 0 additions & 1 deletion .github/workflows/pr-ci-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ jobs:
./gradlew checkstyleMain checkstyleTest --continue
test:
name: pr-ci-pipeline
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ dependencies {

// swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0'

// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.redisson:redisson-spring-boot-starter:3.18.0'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.kpop.ticketing.domain.common.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.kpop.ticketing.domain.common.aspect;

import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
@Aspect
@Order(value = 1)
public class DistributedLockAspect {

private final RedissonClient redissonClient;

@Around("@annotation(com.kpop.ticketing.domain.common.annotation.DistributedLock)")
public Object lock(final ProceedingJoinPoint joinPoint) throws Throwable {
// joinPoint는 호출된 메서드의 인자 정보를 가지고 있음
Long seatId = (Long) joinPoint.getArgs()[1];
RLock rLock = redissonClient.getLock(String.format("lock:%s", seatId));

try {
if (!rLock.tryLock()) {
return false;
}
Object returnValue = joinPoint.proceed();
rLock.unlock();
return returnValue;
} catch (final Exception e) {
Thread.currentThread().interrupt();
throw new InterruptedException();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.kpop.ticketing.presentation.reservation.usecase;

import com.kpop.ticketing.domain.common.annotation.DistributedLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -27,12 +29,13 @@ public class ReserveSeatUseCase {
private final ReservationStore reservationStore;
private final WaitTokenReader waitTokenReader;

@DistributedLock
public void execute(String token, Long seatId) {
WaitToken waitToken = waitTokenReader.getWaitTokenByToken(token);

User user = userReader.getUser(waitToken.getUser().getId());
// 비관적락으로 seat 조회
Seat seat = seatReader.getSeatForUpdate(seatId);
Seat seat = seatReader.getSeat(seatId);

// 좌석 상태체크
seat.validateSeatStatus();
Expand Down
4 changes: 4 additions & 0 deletions src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ spring:
format_sql: true
show_sql: true
open-in-view: false
data:
redis:
host: localhost
port: 6379
4 changes: 4 additions & 0 deletions src/main/resources/application-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ spring:
format_sql: true
show_sql: true
open-in-view: false
data:
redis:
host: localhost
port: 6379
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ void reserveSeatUseCaseConcurrencyTest() throws InterruptedException {

countDownLatch.await();
executorService.shutdown();

assertThat(count.get()).isEqualTo(1);
assertThat(reservationJpaRepository.findAll().size()).isEqualTo(1);
}
}
4 changes: 4 additions & 0 deletions src/test/resources/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ spring:
database-platform: H2
hibernate:
ddl-auto: update
data:
redis:
host: localhost
port: 6379

0 comments on commit 0e8acf5

Please sign in to comment.