From 365a2a37ae6b91dd6f4601bc95e89f294210308f Mon Sep 17 00:00:00 2001 From: pricelees Date: Tue, 7 Oct 2025 22:19:39 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=83=88=EB=A1=9C=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=A0=20Order=EC=97=90=EC=84=9C=20=EA=B0=80=EC=A0=B8?= =?UTF-8?q?=EC=98=AC=20ReservationStateResponse=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EB=B0=8F=20PAYMENT=5FIN=5FPROGRESS=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EB=B3=80=EA=B2=BD=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business/ReservationService.kt | 37 +++++++++++++++---- .../reservation/dto/ReservationFindDTO.kt | 7 ++++ .../persistence/ReservationRepository.kt | 6 +++ .../mapper/ReservationMappingExtensions.kt | 8 ++++ 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/ReservationService.kt b/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/ReservationService.kt index 6be365ad..8496801d 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/ReservationService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/ReservationService.kt @@ -4,17 +4,14 @@ import com.sangdol.common.persistence.IDGenerator import com.sangdol.roomescape.common.types.CurrentUserContext import com.sangdol.roomescape.payment.business.PaymentService import com.sangdol.roomescape.payment.dto.PaymentResponse -import com.sangdol.roomescape.reservation.dto.PendingReservationCreateRequest -import com.sangdol.roomescape.reservation.dto.PendingReservationCreateResponse -import com.sangdol.roomescape.reservation.dto.ReservationCancelRequest -import com.sangdol.roomescape.reservation.dto.ReservationAdditionalResponse -import com.sangdol.roomescape.reservation.dto.ReservationOverviewListResponse -import com.sangdol.roomescape.reservation.mapper.toEntity -import com.sangdol.roomescape.reservation.mapper.toOverviewResponse -import com.sangdol.roomescape.reservation.mapper.toAdditionalResponse +import com.sangdol.roomescape.reservation.dto.* import com.sangdol.roomescape.reservation.exception.ReservationErrorCode import com.sangdol.roomescape.reservation.exception.ReservationException import com.sangdol.roomescape.reservation.infrastructure.persistence.* +import com.sangdol.roomescape.reservation.mapper.toAdditionalResponse +import com.sangdol.roomescape.reservation.mapper.toEntity +import com.sangdol.roomescape.reservation.mapper.toOverviewResponse +import com.sangdol.roomescape.reservation.mapper.toStateResponse import com.sangdol.roomescape.schedule.business.ScheduleService import com.sangdol.roomescape.schedule.dto.ScheduleStateResponse import com.sangdol.roomescape.schedule.dto.ScheduleWithThemeAndStoreResponse @@ -142,6 +139,30 @@ class ReservationService( } } + @Transactional(readOnly = true) + fun findStatusWithLock(id: Long): ReservationStateResponse { + log.info { "[findStatusWithLock] 예약 LOCK + 상태 조회 시작: reservationId=${id}" } + + return reservationRepository.findByIdForUpdate(id)?.let { + log.info { "[findStatusWithLock] 예약 LOCK + 상태 조회 완료: reservationId=${id}" } + it.toStateResponse() + } ?: run { + log.warn { "[findStatusWithLock] 예약 LOCK + 상태 조회 실패: reservationId=${id}" } + throw ReservationException(ReservationErrorCode.RESERVATION_NOT_FOUND) + } + } + + @Transactional + fun markInProgress(reservationId: Long) { + log.info { "[markInProgress] 예약 상태 ${ReservationStatus.PAYMENT_IN_PROGRESS} 변경 시작." } + + findOrThrow(reservationId).apply { + this.status = ReservationStatus.PAYMENT_IN_PROGRESS + }.also { + log.info { "[markInProgress] 예약 상태 ${ReservationStatus.PAYMENT_IN_PROGRESS} 변경 완료" } + } + } + private fun findOrThrow(id: Long): ReservationEntity { log.info { "[findOrThrow] 예약 조회 시작: reservationId=${id}" } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/reservation/dto/ReservationFindDTO.kt b/service/src/main/kotlin/com/sangdol/roomescape/reservation/dto/ReservationFindDTO.kt index 7244a70f..29737d9c 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/reservation/dto/ReservationFindDTO.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/reservation/dto/ReservationFindDTO.kt @@ -35,3 +35,10 @@ data class ReserverInfo( data class ReservationOverviewListResponse( val reservations: List ) + +data class ReservationStateResponse( + val id: Long, + val scheduleId: Long, + val status: ReservationStatus, + val createdAt: Instant +) diff --git a/service/src/main/kotlin/com/sangdol/roomescape/reservation/infrastructure/persistence/ReservationRepository.kt b/service/src/main/kotlin/com/sangdol/roomescape/reservation/infrastructure/persistence/ReservationRepository.kt index 7d1827f9..29a3500a 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/reservation/infrastructure/persistence/ReservationRepository.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/reservation/infrastructure/persistence/ReservationRepository.kt @@ -1,6 +1,8 @@ package com.sangdol.roomescape.reservation.infrastructure.persistence +import jakarta.persistence.LockModeType import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.jpa.repository.Lock import org.springframework.data.jpa.repository.Modifying import org.springframework.data.jpa.repository.Query import org.springframework.data.repository.query.Param @@ -10,6 +12,10 @@ interface ReservationRepository : JpaRepository { fun findAllByUserIdAndStatusIsIn(userId: Long, statuses: List): List + @Lock(LockModeType.PESSIMISTIC_WRITE) + @Query("SELECT r FROM ReservationEntity r WHERE r._id = :id") + fun findByIdForUpdate(@Param("id") id: Long): ReservationEntity? + @Modifying @Query( """ diff --git a/service/src/main/kotlin/com/sangdol/roomescape/reservation/mapper/ReservationMappingExtensions.kt b/service/src/main/kotlin/com/sangdol/roomescape/reservation/mapper/ReservationMappingExtensions.kt index 052fffd4..33762eeb 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/reservation/mapper/ReservationMappingExtensions.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/reservation/mapper/ReservationMappingExtensions.kt @@ -4,6 +4,7 @@ import com.sangdol.roomescape.payment.dto.PaymentResponse import com.sangdol.roomescape.reservation.dto.PendingReservationCreateRequest import com.sangdol.roomescape.reservation.dto.ReservationAdditionalResponse import com.sangdol.roomescape.reservation.dto.ReservationOverviewResponse +import com.sangdol.roomescape.reservation.dto.ReservationStateResponse import com.sangdol.roomescape.reservation.dto.ReserverInfo import com.sangdol.roomescape.reservation.infrastructure.persistence.ReservationEntity import com.sangdol.roomescape.reservation.infrastructure.persistence.ReservationStatus @@ -57,3 +58,10 @@ private fun ReservationEntity.toReserverInfo() = ReserverInfo( participantCount = this.participantCount, requirement = this.requirement ) + +fun ReservationEntity.toStateResponse() = ReservationStateResponse( + id = this.id, + scheduleId = this.scheduleId, + status = this.status, + createdAt = this.createdAt +)