Skip to content

Commit 536904a

Browse files
authored
refactor: 대기열 이탈 시 즉시 좌석 AVAILABLE
1 parent 07e7be4 commit 536904a

3 files changed

Lines changed: 44 additions & 13 deletions

File tree

backend/src/main/java/com/back/api/queue/service/QueueEntryProcessService.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.back.api.queue.dto.response.ProcessEntriesResponse;
1818
import com.back.api.queue.dto.response.WaitingQueueBatchEventResponse;
1919
import com.back.api.queue.dto.response.WaitingQueueResponse;
20+
import com.back.api.ticket.service.TicketService;
2021
import com.back.domain.event.entity.Event;
2122
import com.back.domain.event.repository.EventRepository;
2223
import com.back.domain.notification.systemMessage.QueueEntriesMessage;
@@ -51,6 +52,7 @@ public class QueueEntryProcessService {
5152
private final QueueSchedulerProperties properties;
5253
private final QueueEntryReadService queueEntryReadService;
5354
private final EventRepository eventRepository;
55+
private final TicketService ticketService;
5456

5557

5658
/* ==================== 입장 처리 ==================== */
@@ -102,9 +104,9 @@ public void processEventQueueEntries(Event event) {
102104
Long totalWaitingCount;
103105

104106
try {
105-
totalWaitingCount = queueEntryRedisRepository.getTotalWaitingCount(eventId);
107+
totalWaitingCount = queueEntryRedisRepository.getTotalWaitingCount(eventId);
106108
} catch (Exception e) {
107-
log.warn("Redis 조회 실패, DB로부터 대기 중 인원 수 조회 시도 - eventId: {}", eventId, e);
109+
log.warn("Redis 조회 실패, DB로부터 대기 중 인원 수 조회 시도 - eventId: {}", eventId, e);
108110
totalWaitingCount = queueEntryRepository.countByEvent_IdAndQueueEntryStatus(
109111
eventId,
110112
QueueEntryStatus.WAITING
@@ -121,14 +123,13 @@ public void processEventQueueEntries(Event event) {
121123
try {
122124
currentEnteredCount = queueEntryRedisRepository.getTotalEnteredCount(eventId);
123125
} catch (Exception e) {
124-
log.warn("Redis 조회 실패, DB로부터 입장 완료된 인원 수 조회 시도 - eventId: {}", eventId, e);
126+
log.warn("Redis 조회 실패, DB로부터 입장 완료된 인원 수 조회 시도 - eventId: {}", eventId, e);
125127
currentEnteredCount = queueEntryRepository.countByEvent_IdAndQueueEntryStatus(
126128
eventId,
127129
QueueEntryStatus.ENTERED
128130
);
129131
}
130132

131-
132133
int maxEnteredLimit = properties.getEntry().getMaxEnteredLimit();
133134

134135
//입장 가능한 인원 확인
@@ -153,16 +154,14 @@ public void processEventQueueEntries(Event event) {
153154
log.info("입장 처리 - eventId: {}, 대기: {}명, 입장완료: {}명, 빈자리: {}명, 배치사이즈: {}명, 입장시킬인원: {}명",
154155
eventId, totalWaitingCount, currentEnteredCount, availableEnteredCount, batchSize, entryCount);
155156

156-
157-
158157
List<Long> userIds;
159158
try {
160159
Set<Object> topWaitingUsers = queueEntryRedisRepository.getTopWaitingUsers(eventId, entryCount);
161160
userIds = topWaitingUsers.stream()
162161
.map(obj -> Long.parseLong(obj.toString()))
163162
.toList();
164163
} catch (Exception e) {
165-
log.warn("Redis 조회 실패, DB로부터 상위 대기 인원 조회 시도 - eventId: {}", eventId, e);
164+
log.warn("Redis 조회 실패, DB로부터 상위 대기 인원 조회 시도 - eventId: {}", eventId, e);
166165
userIds = queueEntryRepository.findTopNWaitingUsers(eventId, entryCount);
167166
}
168167

@@ -358,7 +357,6 @@ public void expireBatchEntries(List<QueueEntry> entries) {
358357

359358
/* ==================== 결제 완료 처리 ==================== */
360359

361-
362360
@Transactional
363361
public void completePayment(Long eventId, Long userId) {
364362

@@ -443,6 +441,8 @@ public MoveToBackResponse moveToBackQueue(Long eventId, Long userId) {
443441

444442
int previousRank = queueEntry.getQueueRank();
445443

444+
ticketService.releaseDraftTicketAndSeat(eventId, userId);
445+
446446
Long maxRank = queueEntryRepository.findMaxRankInQueue(eventId)
447447
.orElse(0L);
448448

@@ -470,7 +470,6 @@ public MoveToBackResponse moveToBackQueue(Long eventId, Long userId) {
470470

471471
}
472472

473-
474473
private void validateEntry(QueueEntry queueEntry) {
475474
QueueEntryStatus status = queueEntry.getQueueEntryStatus();
476475

@@ -519,7 +518,6 @@ private void validatePaymentCompletion(QueueEntry queueEntry) {
519518
}
520519
}
521520

522-
523521
private void updateRedis(Long eventId, Long userId) {
524522
try {
525523
queueEntryRedisRepository.moveToEnteredQueue(eventId, userId);
@@ -531,7 +529,6 @@ private void updateRedis(Long eventId, Long userId) {
531529
}
532530
}
533531

534-
535532
private void publishEnteredEvent(QueueEntry queueEntry) {
536533
EnteredQueueResponse response = EnteredQueueResponse.from(
537534
queueEntry.getUserId(),

backend/src/main/java/com/back/api/ticket/service/TicketService.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.back.api.ticket.service;
22

33
import java.util.List;
4+
import java.util.Optional;
45

56
import org.springframework.stereotype.Service;
67
import org.springframework.transaction.annotation.Transactional;
@@ -23,12 +24,14 @@
2324
import com.back.global.error.exception.ErrorException;
2425

2526
import lombok.RequiredArgsConstructor;
27+
import lombok.extern.slf4j.Slf4j;
2628

2729
/**
2830
* 티켓 상태 변경 담당 서비스
2931
*/
3032
@Service
3133
@RequiredArgsConstructor
34+
@Slf4j
3235
public class TicketService {
3336

3437
private final TicketRepository ticketRepository;
@@ -202,4 +205,31 @@ public void expireDraftTicket(Long ticketId) {
202205
seatService.markSeatAsAvailable(ticket.getSeat());
203206
}
204207
}
208+
209+
public void releaseDraftTicketAndSeat(Long eventId, Long userId) {
210+
try {
211+
Optional<Ticket> draftTicketOpt =
212+
ticketRepository.findByEventIdAndOwnerIdAndTicketStatus(
213+
eventId, userId, TicketStatus.DRAFT
214+
);
215+
216+
if (draftTicketOpt.isEmpty()) {
217+
return;
218+
}
219+
220+
Ticket draftTicket = draftTicketOpt.get();
221+
draftTicket.cancel();
222+
223+
if (draftTicket.getSeat() != null) {
224+
seatService.markSeatAsAvailable(draftTicket.getSeat());
225+
}
226+
227+
} catch (Exception e) {
228+
log.warn(
229+
"Draft ticket release failed on queue demotion (scheduler will handle) " +
230+
"- eventId={}, userId={}",
231+
eventId, userId, e
232+
);
233+
}
234+
}
205235
}

backend/src/test/java/com/back/api/queue/service/QueueEntryProcessServiceTest.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.back.api.queue.dto.response.EnteredQueueResponse;
2525
import com.back.api.queue.dto.response.ExpiredQueueResponse;
2626
import com.back.api.queue.dto.response.MoveToBackResponse;
27+
import com.back.api.ticket.service.TicketService;
2728
import com.back.config.TestRedisConfig;
2829
import com.back.domain.event.entity.Event;
2930
import com.back.domain.event.repository.EventRepository;
@@ -62,6 +63,9 @@ class QueueEntryProcessServiceTest {
6263
@Mock
6364
private EventRepository eventRepository;
6465

66+
@Mock
67+
private TicketService ticketService;
68+
6569
private QueueSchedulerProperties queueSchedulerProperties;
6670

6771
private Event testEvent;
@@ -89,7 +93,8 @@ void setUp() {
8993
eventPublisher,
9094
queueSchedulerProperties,
9195
queueEntryReadService,
92-
eventRepository
96+
eventRepository,
97+
ticketService
9398
);
9499

95100
testEvent = EventFactory.fakeEvent("TestEvent");
@@ -907,7 +912,6 @@ void moveToBackQueue_NotEnteredStatus_Completed() {
907912
then(queueEntryRepository).should(never()).save(any());
908913
}
909914

910-
911915
}
912916

913917
}

0 commit comments

Comments
 (0)