From dbc6847877ca6661faecee8d11c8120c35d70fc0 Mon Sep 17 00:00:00 2001 From: pricelees Date: Fri, 3 Oct 2025 15:24:26 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20Pending=20=EC=98=88=EC=95=BD=20?= =?UTF-8?q?=EB=AF=B8=EC=83=9D=EC=84=B1=20=EC=9D=BC=EC=A0=95=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=8A=A4=EC=BC=80=EC=A5=B4=EB=A7=81=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=EC=97=90=EC=84=9C=20=EB=B0=9C=EC=83=9D=ED=95=A0=20?= =?UTF-8?q?=EC=88=98=20=EC=9E=88=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=9D=BC=EC=A0=95=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=8B=9C=20Pessimistic=20Lock=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reservation/business/ReservationService.kt | 2 +- .../roomescape/schedule/business/ScheduleService.kt | 10 ++++++++-- .../persistence/ScheduleRepository.kt | 13 +++++++++++++ 3 files changed, 22 insertions(+), 3 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 498b6ced..61587cde 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 @@ -154,7 +154,7 @@ class ReservationService( } private fun validateCanCreate(request: PendingReservationCreateRequest) { - val schedule = scheduleService.findSummaryById(request.scheduleId) + val schedule = scheduleService.findSummaryWithLock(request.scheduleId) val theme = themeService.findInfoById(schedule.themeId) reservationValidator.validateCanCreate(schedule, theme, request) diff --git a/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleService.kt b/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleService.kt index 02325f72..91b4e2dc 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleService.kt @@ -174,10 +174,16 @@ class ScheduleService( // Other-Service (API 없이 다른 서비스에서 호출) // ======================================== @Transactional(readOnly = true) - fun findSummaryById(id: Long): ScheduleSummaryResponse { + fun findSummaryWithLock(id: Long): ScheduleSummaryResponse { log.info { "[ScheduleService.findDateTimeById] 일정 개요 조회 시작 : id=$id" } - return findOrThrow(id).toSummaryResponse() + val schedule: ScheduleEntity = scheduleRepository.findByIdForUpdate(id) + ?: run { + log.warn { "[ScheduleService.updateSchedule] 일정 조회 실패. id=$id" } + throw ScheduleException(ScheduleErrorCode.SCHEDULE_NOT_FOUND) + } + + return schedule.toSummaryResponse() .also { log.info { "[ScheduleService.findDateTimeById] 일정 개요 조회 완료: id=$id" } } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/schedule/infrastructure/persistence/ScheduleRepository.kt b/service/src/main/kotlin/com/sangdol/roomescape/schedule/infrastructure/persistence/ScheduleRepository.kt index ab70893e..a30fbbed 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/schedule/infrastructure/persistence/ScheduleRepository.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/schedule/infrastructure/persistence/ScheduleRepository.kt @@ -1,7 +1,9 @@ package com.sangdol.roomescape.schedule.infrastructure.persistence import com.sangdol.roomescape.schedule.business.domain.ScheduleOverview +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 @@ -11,6 +13,17 @@ import java.time.LocalTime interface ScheduleRepository : JpaRepository { + @Lock(value = LockModeType.PESSIMISTIC_WRITE) + @Query(""" + SELECT + s + FROM + ScheduleEntity s + WHERE + s._id = :id + """) + fun findByIdForUpdate(id: Long): ScheduleEntity? + @Query( """ SELECT