작성
·
260
·
수정됨
0
안녕하세요,
동시성 이슈에 대한 이야기를 해주시면서 "등록 시도를 했는데 유니크에서 튕겼다면 누군가 먼저 신규 번호를 선점했다는 뜻이니 3회 이상 재시도를 자동으로 하게 하는 방법으로 풀 수 있다"란 말씀을 해주셨습니다.
그래서 아래 예시 코드처럼 DataIntegrityViolationException 을 try-catch
로 잡아서 재시도를 하라는 뜻으로 이해했습니다. (하지만 로컬에서 동시성 문제를 발생시키는 방법을 찾지 못해 맞는 코드인지 모르겠습니다.. @Transactional
이 있다면 DataIntegrityViolationException 를 잡기 위해서 try-catch
블럭 내부에서 flush()
를 호출하기 위해 saveAndFlush()
를 사용한다는 말도 있더라구요?)
public ExampleEntity save(ExampleEntity entity) {
for (int i = 0; i < 3; i++) {
try {
// 저장 시도
return repository.save(entity);
} catch (DataIntegrityViolationException e) {
// 유니크 제약 조건 위배 예외 처리
log.info("저장 실패");
}
}
throw new RuntimeException("저장에 실패했습니다.");
}
이러한 방법이 맞다면 더 좋은 방법이 있는지, 혹시 만약 이 방법이 아니라면 어떤 방법으로 해결할 수 있는지 알려주시면 감사하겠습니다.
좋은 강의 항상 감사드립니다.
답변 1
0
안녕하세요, lch9502 님!
접근하신 방법이 맞습니다. 몇 가지 좀 더 말씀드리자면요. ㅎㅎ
테스트 코드를 통해 동시성 테스트를 할 수 있습니다. ExecutorService를 통해 스레드풀을 만들고 동시에 요청을 발생시키는 방법을 한번 찾아보셔도 좋을 것 같습니다 ㅎㅎ
위와 같은 재시도 방법의 경우, 비즈니스 플로우 상 크게 중요도가 높지 않은 케이스(즉, 3번 시도 후 실패해도 기능 상 중요하지 않거나, 사용자가 다시 요청을 하는 행위가 비용이 크지 않은 경우)에서 간단하게 시도해볼 수 있는 방법입니다. 만약 요청의 성공을 보장해야 하는 경우, 레디스 등을 활용한 분산락 같이 동시성 이슈를 해소하기 위한 여러가지 기법을 적용해볼 수 있으니 참고해 주세요.
도움이 되셨기를 바랍니다.
감사합니다. 🙂