diff --git a/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceLockAspect.java b/src/main/java/nbc/ticketing/ticket911/common/aop/LettuceLockAspect.java similarity index 86% rename from src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceLockAspect.java rename to src/main/java/nbc/ticketing/ticket911/common/aop/LettuceLockAspect.java index f8a8c0a..26f1958 100644 --- a/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceLockAspect.java +++ b/src/main/java/nbc/ticketing/ticket911/common/aop/LettuceLockAspect.java @@ -1,4 +1,4 @@ -package nbc.ticketing.ticket911.common.lock.lettuce; +package nbc.ticketing.ticket911.common.aop; import java.lang.reflect.Method; import java.util.UUID; @@ -13,7 +13,9 @@ import org.springframework.stereotype.Component; import lombok.RequiredArgsConstructor; -import nbc.ticketing.ticket911.common.lock.RedissonLock; + +import nbc.ticketing.ticket911.common.lock.RedissonMultiLock; +import nbc.ticketing.ticket911.infrastructure.lettuce.LettuceLockManager; import nbc.ticketing.ticket911.domain.booking.exception.BookingException; import nbc.ticketing.ticket911.domain.booking.exception.code.BookingExceptionCode; @@ -24,7 +26,7 @@ public class LettuceLockAspect { private final LettuceLockManager lockManager; @Around("@annotation(redissonLock)") - public Object lock(ProceedingJoinPoint joinPoint, RedissonLock redissonLock) throws Throwable { + public Object lock(ProceedingJoinPoint joinPoint, RedissonMultiLock redissonLock) throws Throwable { String key = resolveKey(joinPoint, redissonLock); String lockKey = "lock:" + (redissonLock.group().isEmpty() ? "" : redissonLock.group() + ":") + key; String lockValue = UUID.randomUUID().toString(); @@ -41,7 +43,7 @@ public Object lock(ProceedingJoinPoint joinPoint, RedissonLock redissonLock) thr } } - private String resolveKey(ProceedingJoinPoint joinPoint, RedissonLock redissonLock) { + private String resolveKey(ProceedingJoinPoint joinPoint, RedissonMultiLock redissonLock) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); String[] parameterNames = signature.getParameterNames(); diff --git a/src/main/java/nbc/ticketing/ticket911/common/aop/RedissonMultiLockAspect.java b/src/main/java/nbc/ticketing/ticket911/common/aop/RedissonMultiLockAspect.java index 7493bd5..35a9bf7 100644 --- a/src/main/java/nbc/ticketing/ticket911/common/aop/RedissonMultiLockAspect.java +++ b/src/main/java/nbc/ticketing/ticket911/common/aop/RedissonMultiLockAspect.java @@ -18,7 +18,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import nbc.ticketing.ticket911.common.annotation.RedissonMultiLock; +import nbc.ticketing.ticket911.common.lock.RedissonMultiLock; import nbc.ticketing.ticket911.domain.lock.LockRedisService; import nbc.ticketing.ticket911.infrastructure.redisson.exception.LockRedisException; import nbc.ticketing.ticket911.infrastructure.redisson.exception.code.LockRedisExceptionCode; diff --git a/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceConfig.java b/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceConfig.java deleted file mode 100644 index 3e2fbcc..0000000 --- a/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package nbc.ticketing.ticket911.common.lock.lettuce; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import io.lettuce.core.RedisClient; - - -@Configuration -public class LettuceConfig { - - @Value("${redis.host}") - private String redisHost; - - @Value("${redis.port}") - private int redisPort; - - @Bean - public RedisClient redisClient() { - return RedisClient.create("redis://" + redisHost + ":" + redisPort); - } -} diff --git a/src/main/java/nbc/ticketing/ticket911/config/LettuceConfig.java b/src/main/java/nbc/ticketing/ticket911/config/RedisConfig.java similarity index 70% rename from src/main/java/nbc/ticketing/ticket911/config/LettuceConfig.java rename to src/main/java/nbc/ticketing/ticket911/config/RedisConfig.java index 0f40d90..f57f932 100644 --- a/src/main/java/nbc/ticketing/ticket911/config/LettuceConfig.java +++ b/src/main/java/nbc/ticketing/ticket911/config/RedisConfig.java @@ -7,12 +7,15 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import io.lettuce.core.RedisClient; + @Configuration -public class LettuceConfig { +public class RedisConfig { - @Value("${redis.host}") + @Value("${data.redis.host}") private String redisHost; - @Value("${redis.port}") + + @Value("${data.redis.port}") private int redisPort; @Bean @@ -22,4 +25,9 @@ public RedissonClient redissonClient() { .setAddress("redis://" + redisHost + ":" + redisPort); return Redisson.create(config); } + + @Bean + public RedisClient redisClient() { + return RedisClient.create("redis://" + redisHost + ":" + redisPort); + } } diff --git a/src/main/java/nbc/ticketing/ticket911/domain/booking/application/BookingFacade.java b/src/main/java/nbc/ticketing/ticket911/domain/booking/application/BookingFacade.java index 6a720fc..fb9eb20 100644 --- a/src/main/java/nbc/ticketing/ticket911/domain/booking/application/BookingFacade.java +++ b/src/main/java/nbc/ticketing/ticket911/domain/booking/application/BookingFacade.java @@ -5,7 +5,7 @@ import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; -import nbc.ticketing.ticket911.common.lock.lettuce.DistributedLockService; +import nbc.ticketing.ticket911.infrastructure.lettuce.DistributedLockService; import nbc.ticketing.ticket911.domain.auth.vo.AuthUser; import nbc.ticketing.ticket911.domain.booking.dto.request.BookingRequestDto; import nbc.ticketing.ticket911.domain.booking.dto.response.BookingResponseDto; @@ -25,6 +25,6 @@ public BookingResponseDto createBookingWithLock(AuthUser authUser, BookingReques .toList(); return lockService.runWithLock(lockKeys, 10_000L, - () -> bookingService.createBooking(authUser, dto)); + () -> bookingService.createBookingLettuce(authUser, dto)); } } diff --git a/src/main/java/nbc/ticketing/ticket911/domain/booking/application/BookingService.java b/src/main/java/nbc/ticketing/ticket911/domain/booking/application/BookingService.java index 4098c2f..991e6ea 100644 --- a/src/main/java/nbc/ticketing/ticket911/domain/booking/application/BookingService.java +++ b/src/main/java/nbc/ticketing/ticket911/domain/booking/application/BookingService.java @@ -7,10 +7,8 @@ import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; -import nbc.ticketing.ticket911.common.lock.RedissonLock; -import nbc.ticketing.ticket911.common.lock.lettuce.DistributedLockService; -import nbc.ticketing.ticket911.common.lock.lettuce.LettuceLockManager; -import nbc.ticketing.ticket911.common.annotation.RedissonMultiLock; + +import nbc.ticketing.ticket911.common.lock.RedissonMultiLock; import nbc.ticketing.ticket911.domain.auth.vo.AuthUser; import nbc.ticketing.ticket911.domain.booking.dto.request.BookingRequestDto; import nbc.ticketing.ticket911.domain.booking.dto.response.BookingResponseDto; @@ -35,7 +33,7 @@ public class BookingService { @RedissonMultiLock(key = "#bookingRequestDto.seatIds", group = "concertSeat") @Transactional - public BookingResponseDto createBooking(AuthUser authUser, BookingRequestDto bookingRequestDto) { + public BookingResponseDto createBookingLettuce(AuthUser authUser, BookingRequestDto bookingRequestDto) { User user = userDomainService.findActiveUserById(authUser.getId()); diff --git a/src/main/java/nbc/ticketing/ticket911/domain/booking/controller/BookingController.java b/src/main/java/nbc/ticketing/ticket911/domain/booking/controller/BookingController.java index 3fd0091..6019783 100644 --- a/src/main/java/nbc/ticketing/ticket911/domain/booking/controller/BookingController.java +++ b/src/main/java/nbc/ticketing/ticket911/domain/booking/controller/BookingController.java @@ -15,10 +15,10 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import nbc.ticketing.ticket911.domain.booking.application.BookingFacade; -import nbc.ticketing.ticket911.domain.booking.application.BookingService; import nbc.ticketing.ticket911.common.response.CommonResponse; import nbc.ticketing.ticket911.domain.auth.vo.AuthUser; +import nbc.ticketing.ticket911.domain.booking.application.BookingFacade; +import nbc.ticketing.ticket911.domain.booking.application.BookingService; import nbc.ticketing.ticket911.domain.booking.dto.request.BookingRequestDto; import nbc.ticketing.ticket911.domain.booking.dto.response.BookingResponseDto; @@ -41,6 +41,17 @@ public ResponseEntity> createBooking( .body(CommonResponse.of(true, HttpStatus.CREATED.value(), "예약 성공", bookingResponseDto)); } + @PostMapping("/lettuce") + public ResponseEntity> createBookingLettuce( + @AuthenticationPrincipal AuthUser authUser, + @Valid @RequestBody BookingRequestDto bookingRequestDto) { + + BookingResponseDto bookingResponseDto = bookingFacade.createBookingWithLock(authUser, bookingRequestDto); + + return ResponseEntity.status(HttpStatus.CREATED) + .body(CommonResponse.of(true, HttpStatus.CREATED.value(), "예약 성공", bookingResponseDto)); + } + @GetMapping public ResponseEntity>> getBookings( @AuthenticationPrincipal AuthUser authUser) { diff --git a/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/DistributedLockService.java b/src/main/java/nbc/ticketing/ticket911/infrastructure/lettuce/DistributedLockService.java similarity index 76% rename from src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/DistributedLockService.java rename to src/main/java/nbc/ticketing/ticket911/infrastructure/lettuce/DistributedLockService.java index 544bcd3..75b57da 100644 --- a/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/DistributedLockService.java +++ b/src/main/java/nbc/ticketing/ticket911/infrastructure/lettuce/DistributedLockService.java @@ -1,4 +1,4 @@ -package nbc.ticketing.ticket911.common.lock.lettuce; +package nbc.ticketing.ticket911.infrastructure.lettuce; import java.util.List; import java.util.function.Supplier; diff --git a/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceDistributedLockService.java b/src/main/java/nbc/ticketing/ticket911/infrastructure/lettuce/LettuceDistributedLockService.java similarity index 94% rename from src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceDistributedLockService.java rename to src/main/java/nbc/ticketing/ticket911/infrastructure/lettuce/LettuceDistributedLockService.java index 5a96cee..b376224 100644 --- a/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceDistributedLockService.java +++ b/src/main/java/nbc/ticketing/ticket911/infrastructure/lettuce/LettuceDistributedLockService.java @@ -1,4 +1,4 @@ -package nbc.ticketing.ticket911.common.lock.lettuce; +package nbc.ticketing.ticket911.infrastructure.lettuce; import java.util.List; import java.util.function.Supplier; diff --git a/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceLockManager.java b/src/main/java/nbc/ticketing/ticket911/infrastructure/lettuce/LettuceLockManager.java similarity index 95% rename from src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceLockManager.java rename to src/main/java/nbc/ticketing/ticket911/infrastructure/lettuce/LettuceLockManager.java index e8bca5f..e6d3e0a 100644 --- a/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceLockManager.java +++ b/src/main/java/nbc/ticketing/ticket911/infrastructure/lettuce/LettuceLockManager.java @@ -1,4 +1,4 @@ -package nbc.ticketing.ticket911.common.lock.lettuce; +package nbc.ticketing.ticket911.infrastructure.lettuce; import org.springframework.stereotype.Component; diff --git a/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceMultiLock.java b/src/main/java/nbc/ticketing/ticket911/infrastructure/lettuce/LettuceMultiLock.java similarity index 94% rename from src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceMultiLock.java rename to src/main/java/nbc/ticketing/ticket911/infrastructure/lettuce/LettuceMultiLock.java index e848f14..bf52379 100644 --- a/src/main/java/nbc/ticketing/ticket911/common/lock/lettuce/LettuceMultiLock.java +++ b/src/main/java/nbc/ticketing/ticket911/infrastructure/lettuce/LettuceMultiLock.java @@ -1,4 +1,4 @@ -package nbc.ticketing.ticket911.common.lock.lettuce; +package nbc.ticketing.ticket911.infrastructure.lettuce; import java.util.List; import java.util.UUID; diff --git a/src/test/java/nbc/ticketing/ticket911/domain/booking/application/BookingServiceTest.java b/src/test/java/nbc/ticketing/ticket911/domain/booking/application/BookingServiceTest.java index 4646776..a7f1cd6 100644 --- a/src/test/java/nbc/ticketing/ticket911/domain/booking/application/BookingServiceTest.java +++ b/src/test/java/nbc/ticketing/ticket911/domain/booking/application/BookingServiceTest.java @@ -133,7 +133,7 @@ void setupConcertSeat() { for (int i = 0; i < threadCount; i++) { executor.submit(() -> { try { - bookingService.createBooking(authUser, dto); + bookingService.createBookingLettuce(authUser, dto); results.add("성공"); } catch (BookingException e) { results.add(e.getErrorCode().name()); diff --git a/src/test/java/nbc/ticketing/ticket911/domain/booking/controller/BookingControllerTest.java b/src/test/java/nbc/ticketing/ticket911/domain/booking/controller/BookingControllerTest.java index 17cf819..c8d0630 100644 --- a/src/test/java/nbc/ticketing/ticket911/domain/booking/controller/BookingControllerTest.java +++ b/src/test/java/nbc/ticketing/ticket911/domain/booking/controller/BookingControllerTest.java @@ -117,7 +117,7 @@ void ConcurrencyProblem() throws InterruptedException { for (int i = 0; i < threadCount; i++) { results.add(executor.submit(() -> { try { - bookingService.createBooking(authUser, bookingRequestDto); + bookingService.createBookingLettuce(authUser, bookingRequestDto); return "성공"; } catch (Exception e) { return "실패: " + e.getMessage(); diff --git a/src/test/java/nbc/ticketing/ticket911/domain/lock/BookingConcurrencyTest.java b/src/test/java/nbc/ticketing/ticket911/domain/lock/BookingConcurrencyTest.java index 9fb0d8c..ca3aa08 100644 --- a/src/test/java/nbc/ticketing/ticket911/domain/lock/BookingConcurrencyTest.java +++ b/src/test/java/nbc/ticketing/ticket911/domain/lock/BookingConcurrencyTest.java @@ -14,7 +14,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; import lombok.extern.slf4j.Slf4j; import nbc.ticketing.ticket911.domain.auth.vo.AuthUser; @@ -117,7 +116,7 @@ void setUp() { for (int i = 0; i < THREAD_COUNT; i++) { try { - bookingService.createBooking(authUser, bookingRequestDto); + bookingService.createBookingLettuce(authUser, bookingRequestDto); log.info("[{}] 예매 성공", Thread.currentThread().getName()); successCount.incrementAndGet(); } catch (Exception e) {