작성한 질문수
실습으로 배우는 선착순 이벤트 시스템
Consumer 사용하기
해결된 질문
작성
·
157
수정됨
0
db에 등록도 잘 되었는지 확인해 보기 위해서
coupon 테이블 조회 해보았는데
[coupon_id], [user_id]테스트 로직에서 userId 값은 단순히 for을 통해 0부터 순차적으로 받은 뒤쿠폰 개수에 맞춰 userId 도 0~99 사이의 값이 들어 올 것이라 생각했는데
예상과 다르게 103 이라는 id가 들어왔습니다이런 이유가 궁금합니다
답변 1
Sanghoon Lee 님 테스트 코드와 로직을 어떻게 작성하셨는지 공유해주실 수 있으실까요 ?
@Test public void 여러명응모() throws InterruptedException { int threadCount = 1000; ExecutorService executorService = Executors.newFixedThreadPool(32); CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { long userId = i; executorService.submit(() -> { try { applyService.apply(userId); } finally { latch.countDown();; } }); } latch.await(); Thread.sleep(10000); long count = couponRepositroy.count(); assertThat(count).isEqualTo(100); }
@Service public class ApplyService { private final CouponRepositroy couponRepositroy; private final CouponCountRepository couponCountRepository; private final CouponCreateProducer couponCreateProducer; private final AppliedUserRepository appliedUserRepository; public ApplyService(CouponRepositroy couponRepositroy, CouponCountRepository couponCountRepository, CouponCreateProducer couponCreateProducer, AppliedUserRepository appliedUserRepository) { this.couponRepositroy = couponRepositroy; this.couponCountRepository = couponCountRepository; this.couponCreateProducer = couponCreateProducer; this.appliedUserRepository = appliedUserRepository; } public void apply(Long userId) { Long apply = appliedUserRepository.add(userId); if (apply != 1) { return; } // lock start Long count = couponCountRepository.increment(); if (count > 100) { return; } couponCreateProducer.create(userId); // lock end } }
@Repository public class AppliedUserRepository { private final RedisTemplate<String, String> redisTemplate; public AppliedUserRepository(RedisTemplate<String, String> redisTemplate) { this.redisTemplate = redisTemplate; } public Long add(Long userId) { return redisTemplate .opsForSet() .add("applied_user", userId.toString()); } }
Sanghoon Lee 님 안녕하세요.답변이 늦어져서 죄송하다는 말씀 먼저 드립니다.
여러개의 스레드풀을 이용하여 병렬적으로 실행하면 실행하는 순서가 보장되지 않습니다.예를들어 1~100 번의 id 를 가진 유저가 먼저 요청하지만 먼저 실행이 된다는 보장은 없습니다.
해당 내용에 대해 궁금하시다면 멀티스레드에 대해 공부해보시면 좋을것 같습니다!
테스트 코드 입니다
ApplyService
AppliedUserRepository