Entity
연관관계의 문제점 해결오늘은 필수 과제를 진행하기 전 단계를 마무리했습니다.
Thread
가 동시에 동시성 이슈가 발생하는 메소드를 호출하는 시나리오를 토대로 테스트 코드를 작성ExecutorService
, CyclicBarrier
활용가능Coroutine
활용 가능@SpringBootTest
public class BookingServiceTest {
@Autowired
private BookingService bookingService;
@Test
void 동시성_이슈를_검증할_수_있는_테스트_코드_작성() throws InterruptedException {
// 예약을 테스트할 Screening, User 및 좌석 ID를 세팅함
Long userId = 1L;
Long screeningId = 1L;
List<Long> seatIds = List.of(101L); // 동일한 좌석 ID로 테스트
BookingCreateRequest request = new BookingCreateRequest(seatIds);
// Thread 동시 실행을 위한 설정
int numberOfThreads = 10; // 동시 실행할 Thread 개수
ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads);
CyclicBarrier barrier = new CyclicBarrier(numberOfThreads);
List<Future<Long>> results = new ArrayList<>();
for (int i = 0; i < numberOfThreads; i++) {
results.add(executorService.submit(() -> {
// 모든 Thread가 준비될 때까지 대기
barrier.await();
// registration 메소드 호출
return bookingService.registration(userId, screeningId, request);
}));
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.MINUTES);
// 성공적으로 예약된 ID는 하나여야 하며, 나머지는 실패하거나 예외를 반환
int successfulCount = 0;
int failedCount = 0;
for (Future<Long> result : results) {
try {
result.get(); // 성공적인 예약
successfulCount++;
} catch (ExecutionException e) {
if (e.getCause() instanceof RuntimeException) {
failedCount++;
}
}
}
// 단 하나의 성공과 나머지 실패를 검증
assert successfulCount == 1;
assert failedCount == numberOfThreads - 1;
}
}