23.07.02 11:15 작성
·
530
·
수정됨
0
분명 현재 없는 상태이고
결과가 자꾸 이상하게 나와서 sout 처리를 잠시 해보았습니다
package com.example.api.service;
import com.example.api.domain.Coupon;
import com.example.api.repository.CouponCountRepository;
import com.example.api.repository.CouponRepository;
import org.springframework.stereotype.Service;
@Service
public class ApplyService {
private final CouponRepository couponRepository;
private final CouponCountRepository couponCountRepository;
public ApplyService(CouponRepository couponRepository, CouponCountRepository couponCountRepository) {
this.couponRepository = couponRepository;
this.couponCountRepository = couponCountRepository;
}
public void applyV1(Long userId) {
Long count = couponRepository.count();
if(count > 100) {
return;
}
couponRepository.save(new Coupon(userId));
}
public void applyV2(Long userId) {
Long count = couponCountRepository.increment();
System.out.println(count);
if(count > 100) {
return;
}
couponRepository.save(new Coupon(userId));
}
}
@SpringBootTest
class ApplyServiceTest {
@Autowired
private ApplyService applyService;
@Autowired
private CouponRepository couponRepository;
@Test
public void applyOnce() {
applyService.applyV1(1L);
long count = couponRepository.count();
Assertions.assertEquals(1L, count);
}
@Test
public void 여러명응모V1() 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.applyV1(userId);
} catch(Exception e) {
System.out.println(e);
}finally {
latch.countDown();
}
});
}
latch.await();
long count = couponRepository.count();
assertThat(count).isEqualTo(100);
}
@Test
public void 여러명응모V2() 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.applyV2(userId);
} catch(Exception e) {
System.out.println(e);
}finally {
latch.countDown();
}
});
}
latch.await();
long count = couponRepository.count();
org.assertj.core.api.Assertions.assertThat(count).isEqualTo(100);
}
}
그런데 여러명응모V2 test를 실행시에 count를 출력시
다음과 같은 수가 나옵니다.
20003
20011
20012
20013
20015
20016
20017
20018
20020
20022
???
한번 할때마다 1000씩 쿠폰의 수가 증가중인데요;;;
조회했을때는 empty라 나오는데 이렇게 되는 연유를 잘 모르갰습니다.
테스트 코드라서 rollback이 되야할거 같은데 그렇지 않는것도 잘 모르겟네요;; ㅠㅠ
답변 1
0
2023. 07. 04. 01:33
seonjun Moon 님 안녕하세요.
강의내용과 동일하다면 CouponCountRepository 는 redis 를 사용하는 Repository 로 보입니다.
이 Repository 의 increment 는 현재 쿠폰의 개수와는 상관없이 1개를 증가시키는 로직을 가지고 있습니다.
그리고 증가시킨 쿠폰의 개수가 100 개보다 많다면 쿠폰을 발급하지 않는것은 ApplyService 에서 담당하고 있습니다.
즉 현재 출력되는 것은 정확하게 말씀드리면 "현재 발급된 쿠폰의 개수" 보다는 "쿠폰을 발급요청한 요청의 수" 기때문에 출력되는 숫자가 많은것이 맞습니다.
숫자가 초기화가 되지 않는이유는 redis 는 테스트케이스를 실행시킬때마다 초기화가 되지 않기때문입니다.
이를 자동으로 초기화를 시키려면 beforeAfter 를 이용하여 테스트케이스가 실행된 후에 Redis 의 값을 초기화 해주시면 됩니다.
감사합니다 :)
2023. 07. 04. 22:16
답변 감사합니다 :) 밤늦게 고생하시네요 ㅠㅠ