DB - Unique Key Concurrency

dragonappear·2023년 4월 15일
0

SURLF

목록 보기
6/9


문제점

  • 문제점: 링크
    • short_id 컬럼은 unique column인데, 동일한 short_id 값을 가진 데이터가 동시에 DB에 insert될 경우 데이터베이스에서는 중복오류가 발생할 것이다. (jpa의 경우 DataIntegrityViolationException)
@Service
@Transactional
@RequiredArgsConstructor
public class ShortLinkService {

    private final ShortLinkRepository shortLinkRepository;

    public ShortLinkEntity createShortLink(String url, String clientIp, String userAgent) {
        String randomShortId = createRandomShortId();
        ShortLinkEntity newShortLinkEntity = ShortLinkEntity.createShortUrlEntity(url, randomShortId, clientIp, userAgent);
        return shortLinkRepository.save(newShortLinkEntity);
    }
}
  • 즉, shortLinkRepository.save(newShortLinkEntity); 이 부분에서 에러가 터질 수 있다.

해결방안

  • 정해진 해결방안은 없는 것 같다.
  • 클라이언트보고 다시 요청하라고 하던가, 백엔드에서 처리를 해야한다.
    • 메시지 큐를 이용하던가, 새로운 ShortId로 DB로 Retry를 해야한다.
    • 본문에서는 Retry를 하는 방식으로 문제를 해결하려고 한다.
  • 예외 처리를 5번 반복으로 설정했다. 5번 정도면 거의 불가능한 확률이다.
    public ShortLinkEntity createShortLink(String url, String clientIp, String userAgent) {
        for (int i = 0; i < 5; i++) {
            String randomShortId = createRandomShortId();
            ShortLinkEntity newShortLinkEntity = ShortLinkEntity.createShortUrlEntity(url, randomShortId, clientIp, userAgent);
            Exception exceptionHolder = null;
            try {
                return shortLinkRepository.save(newShortLinkEntity);
            } catch (Exception e) {
                exceptionHolder = e;
            }
        }
        throw new Custom5xxException(EXHAUSTED_SHORT_LINK);
    }
  • 이러한 로직이 반복될 경우, AOP로 로직을 빼버려도 될듯하다.

0개의 댓글