generated from pricelees/issue-pr-template
refactor: 일정 HOLD 로직 수정
- 충돌 방지를 위해 조회시 Lock 추가 - 해당 일정의 시작 시간이 현재 시간 이후인지 검증 로직 추가
This commit is contained in:
parent
1c700130c4
commit
44c556776d
@ -71,19 +71,18 @@ class ScheduleService(
|
||||
@Transactional
|
||||
fun holdSchedule(id: Long) {
|
||||
log.info { "[holdSchedule] 일정 Holding 시작: id=$id" }
|
||||
val result: Int = scheduleRepository.changeStatus(
|
||||
id = id,
|
||||
currentStatus = ScheduleStatus.AVAILABLE,
|
||||
|
||||
val schedule = findForUpdateOrThrow(id).also {
|
||||
scheduleValidator.validateCanHold(it)
|
||||
}
|
||||
|
||||
scheduleRepository.changeStatus(
|
||||
id = schedule.id,
|
||||
currentStatus = schedule.status,
|
||||
changeStatus = ScheduleStatus.HOLD
|
||||
).also {
|
||||
log.info { "[holdSchedule] $it 개의 row 변경 완료" }
|
||||
log.info { "[holdSchedule] 일정 Holding 완료: id=$id" }
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
throw ScheduleException(ScheduleErrorCode.SCHEDULE_NOT_AVAILABLE)
|
||||
}
|
||||
|
||||
log.info { "[holdSchedule] 일정 Holding 완료: id=$id" }
|
||||
}
|
||||
|
||||
// ========================================
|
||||
@ -222,7 +221,18 @@ class ScheduleService(
|
||||
return scheduleRepository.findByIdOrNull(id)
|
||||
?.also { log.info { "[findOrThrow] 일정 조회 완료: id=$id" } }
|
||||
?: run {
|
||||
log.warn { "[updateSchedule] 일정 조회 실패. id=$id" }
|
||||
log.warn { "[findOrThrow] 일정 조회 실패. id=$id" }
|
||||
throw ScheduleException(ScheduleErrorCode.SCHEDULE_NOT_FOUND)
|
||||
}
|
||||
}
|
||||
|
||||
private fun findForUpdateOrThrow(id: Long): ScheduleEntity {
|
||||
log.info { "[findForUpdateOrThrow] 일정 LOCK + 조회 시작: id=$id" }
|
||||
|
||||
return scheduleRepository.findByIdForUpdate(id)
|
||||
?.also { log.info { "[findForUpdateOrThrow] 일정 조회 완료: id=$id" } }
|
||||
?: run {
|
||||
log.warn { "[findForUpdateOrThrow] 일정 조회 실패. id=$id" }
|
||||
throw ScheduleException(ScheduleErrorCode.SCHEDULE_NOT_FOUND)
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +22,15 @@ private val log: KLogger = KotlinLogging.logger {}
|
||||
class ScheduleValidator(
|
||||
private val scheduleRepository: ScheduleRepository
|
||||
) {
|
||||
fun validateCanHold(schedule: ScheduleEntity) {
|
||||
if (schedule.status != ScheduleStatus.AVAILABLE) {
|
||||
log.info { "[validateCanHold] HOLD 실패: id=${schedule.id}, status=${schedule.status}" }
|
||||
throw ScheduleException(ScheduleErrorCode.SCHEDULE_NOT_AVAILABLE)
|
||||
}
|
||||
|
||||
validateNotInPast(schedule.date, schedule.time)
|
||||
}
|
||||
|
||||
fun validateCanDelete(schedule: ScheduleEntity) {
|
||||
val status: ScheduleStatus = schedule.status
|
||||
|
||||
|
||||
@ -155,12 +155,28 @@ class ScheduleApiTest(
|
||||
}
|
||||
}
|
||||
|
||||
test("해당 일정의 시작 시간이 현재 시간 이전이면 실패한다.") {
|
||||
val schedule = dummyInitializer.createSchedule(
|
||||
request = ScheduleFixture.createRequest.copy(
|
||||
date = KoreaDate.today(),
|
||||
time = KoreaTime.now().minusMinutes(1)
|
||||
)
|
||||
)
|
||||
|
||||
runExceptionTest(
|
||||
token = testAuthUtil.defaultUserLogin().second,
|
||||
method = HttpMethod.POST,
|
||||
endpoint = "/schedules/${schedule.id}/hold",
|
||||
expectedErrorCode = ScheduleErrorCode.PAST_DATE_TIME
|
||||
)
|
||||
}
|
||||
|
||||
test("일정이 없으면 실패한다.") {
|
||||
runExceptionTest(
|
||||
token = testAuthUtil.defaultUserLogin().second,
|
||||
method = HttpMethod.POST,
|
||||
endpoint = "/schedules/${INVALID_PK}/hold",
|
||||
expectedErrorCode = ScheduleErrorCode.SCHEDULE_NOT_AVAILABLE
|
||||
expectedErrorCode = ScheduleErrorCode.SCHEDULE_NOT_FOUND
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user