728x90
https://soobysu.tistory.com/127
[Spring] 선착순 이벤트 구현 ( 동시성 Pessimistic Lock)
문제 발급 가능 수량은 100장의 쿠폰이 있다. 10000명이 동시 접근 할때 쿠폰 발급을 정상적으로 수행 가능하게 하려면 어떻게 해야 할까 ? 냅다 코드를 짜버리면 이런식으로 100개 이상의 쿠폰이
soobysu.tistory.com
쿠폰갯수를 10개를 설정해 둔 상태에서 순차적으로 발급 되어서 스레드의 번호가 1~10 까지만 찍힐줄알았다...
@Test
@DisplayName("쿠폰 발급 테스트 (멀티 스레드)")
void couponIssuanceForMultiThreadTest() throws InterruptedException {
AtomicInteger successCount = new AtomicInteger();
int numberOfExecute = 1000;
ExecutorService service = Executors.newFixedThreadPool(1000);
CountDownLatch latch = new CountDownLatch(numberOfExecute);
Coupon mockCoupon = mock(Coupon.class);
Event event = Event.of(requestDto, LocalDateTime.now(), mockCoupon);
when(eventRepository.findByEventIdForUpdate(anyLong())).thenReturn(Optional.ofNullable(event));
for (int i = 0; i < numberOfExecute; i++) {
final int threadNumber = i + 1; // Adding 1 because thread numbers usually start from 1
service.execute(() -> {
try {
eventService.couponIssuance(couponIssuanceRequestDto,threadNumber);
successCount.getAndIncrement();
System.out.println("Thread " + threadNumber + " - 성공");
} catch (PessimisticLockingFailureException e) {
System.out.println("Thread " + threadNumber + " - 락 충돌 감지");
} catch (Exception e) {
System.out.println("Thread " + threadNumber + " - " + e.getMessage());
}
latch.countDown();
});
}
latch.await();
// 성공한 경우의 수가 10개라고 가정.
assertThat(successCount.get()).isEqualTo(10);
}
처음 들어간 스레드 번호를 출력 시켜 주었다.
for (int i = 0; i < numberOfExecute; i++) {
final int threadNumber = i + 1; // Adding 1 because thread numbers usually start from 1
service.execute(() -> {
try {
eventService.couponIssuance(couponIssuanceRequestDto,threadNumber);
public void couponIssuance(CouponIssuanceRequestDto requestDto,int threadNumber) {
Event event = eventRepository.findByEventIdForUpdate(requestDto.getEventId())
.orElseThrow(() -> new IllegalArgumentException("Event is not found"));
Member member = memberService.getMemberByMemberId(requestDto.getMemberId()) ;
//이 부분
System.out.println(threadNumber);
기대한 값은 for문이 1부터 돌기에 1~ 10번 스레드 까지 나오길 기대 했다.
690
544
626
896
79
187
234
983
454
30
---- 10개
674
530
스레드풀에 1000개가 대기 하고 있는 상태에서 1000개가 동시에 접근하므로 1부터 들어오는것이 아닌 1~1000 까지 숫자 중 먼저 접근한 스레드의 번호 부터 찍히는 것이었다.
Thread 234 - 성공
Thread 454 - 성공
Thread 187 - 성공
Thread 690 - 성공
Thread 896 - 성공
Thread 544 - 성공
Thread 30 - 성공
Thread 983 - 성공
Thread 79 - 성공
Thread 626 - 성공
Thread 328 - 남은 쿠폰 수량이 없습니다.
Thread 774 - 남은 쿠폰 수량이 없습니다.
위와 비교해보면 PESSIMISTIC LOCK 은 커밋 후 해제 되기 때문에 정상적으로 먼저 접근된 스레드부터 성공적으로 수행 한 것을 볼 수 있다.
@결론
검증을 못하면 수행과정을 의심할 수 밖에 없으므로 검증실력 또한 열심히 공부하자
728x90
'일-상 > 오류노트' 카테고리의 다른 글
[오류노트] Error handler threw an exception 무한 재시도 (0) | 2024.02.29 |
---|---|
[오류노트] JAVA 프로젝트에 Kotlin 멀티모듈 생성 (2) | 2024.02.12 |
[오류노트] 스프링부트 테스트 contextLoads() FAILED (0) | 2023.11.22 |
[오류노트] 젠킨스 JAVA 17 설치(Feat. 스프링 부트 3.0) (0) | 2023.11.22 |
[오류노트] 로컬환경에서 로컬 도커 컨테이너 접근 (0) | 2023.06.18 |