IMAP 이메일 답신에 따른 리뷰 삭제 처리 기능 구현 중 발생한 문제와 기술적 의사결정 과정

금은체리·2024년 6월 21일
0

1. 문제 정의 및 요구사항 분석

프로젝트의 요구사항은 사용자가 이메일을 통해 리뷰 삭제 요청을 받으면, 해당 이메일의 답신을 기반으로 리뷰를 삭제하거나 상태를 업데이트하는 기능을 구현하는 것이었습니다. 이를 위해 IMAP 프로토콜을 사용하여 이메일 서버와 상호작용하며, 이메일 답신을 분석하여 적절한 데이터베이스 조작을 수행해야 했습니다.

2. 트러블 슈팅 과정

2.1. 외래 키 제약 조건 위반 문제

문제: 리뷰 삭제 시, review_visibility_requests 테이블의 외래 키 제약 조건이 위반되는 오류가 발생했습니다.

  • 오류 메시지: Cannot delete or update a parent row: a foreign key constraint fails

분석 및 해결:

  • 원인: reviews 테이블의 리뷰가 삭제될 때, 해당 리뷰를 참조하는 review_visibility_requests 테이블의 데이터가 남아 있어 외래 키 제약 조건이 위반되었습니다.
  • 해결: 리뷰를 물리적으로 삭제하는 대신, 리뷰의 상태를 DELETED로 업데이트하여 논리적으로 삭제 처리하는 방법을 선택했습니다. 이를 통해 외래 키 제약 조건을 유지하면서 데이터의 무결성을 보장했습니다.
2.2. 이메일 답신 처리 로직 문제

문제: 이메일 답신을 제대로 분석하지 못해, 올바른 리뷰 ID를 추출하거나 답신에 따라 적절한 작업을 수행하지 못하는 문제 발생.

  • 오류 메시지: 리뷰 ID 추출 실패 및 이메일 내용 분석 오류

분석 및 해결:

  • 원인: 이메일 본문에서 리뷰 ID 및 답신 내용을 정확히 추출하는 정규 표현식이 적절하지 않거나, 이메일 형식의 변동성에 의해 발생하는 문제.
  • 해결: 정규 표현식을 개선하고, 다양한 이메일 형식에 대응할 수 있도록 로직을 유연하게 변경했습니다. 이메일 본문 파싱 시, 예외 처리를 강화하여 불완전한 이메일 형식에도 안정적으로 대응할 수 있도록 했습니다.
2.3. 동시성 문제

문제: 다중 스레드 환경에서 동시에 여러 리뷰 삭제 요청을 처리할 때, 데이터 무결성 문제 발생.

  • 오류 메시지: 동시성 관련 예외 또는 데이터 무결성 위반

분석 및 해결:

  • 원인: 다중 스레드가 동시에 동일한 리뷰에 접근하여 삭제 처리 시, 데이터 불일치 또는 충돌 발생.
  • 해결: 데이터베이스 트랜잭션을 사용하여 동시성 제어를 강화했습니다. 각 리뷰 삭제 요청은 트랜잭션 내에서 처리되며, 트랜잭션 롤백 메커니즘을 통해 데이터 무결성을 유지했습니다.

3. 기술적 의사결정

3.1. 논리적 삭제
  • 결정: 외래 키 제약 조건 문제를 해결하기 위해, 리뷰를 물리적으로 삭제하는 대신 상태를 DELETED로 변경하여 논리적으로 삭제하는 방법을 채택했습니다.
  • 이유: 데이터 무결성을 유지하면서도 삭제된 리뷰의 기록을 보존할 수 있으며, 시스템의 안정성을 향상시킵니다.
3.2. IMAP 프로토콜 사용
  • 결정: 이메일 서버와의 상호작용을 위해 IMAP 프로토콜을 사용했습니다.
  • 이유: IMAP는 이메일의 본문과 메타데이터를 효율적으로 검색하고 처리할 수 있는 기능을 제공하여, 이메일 답신을 기반으로 한 리뷰 삭제 기능 구현에 적합합니다.
3.3. 트랜잭션 관리
  • 결정: 데이터베이스 트랜잭션을 사용하여 동시성 문제를 해결했습니다.
  • 이유: 동시성 제어를 통해 데이터 무결성을 유지하고, 다중 스레드 환경에서도 안정적인 동작을 보장할 수 있습니다.

4. 구현 및 결과

4.1. 코드 구현

리뷰 삭제 시, 리뷰의 상태를 DELETED로 변경하는 로직을 추가하고, 이메일 답신을 처리하여 적절한 리뷰를 삭제 또는 상태 업데이트하는 기능을 구현했습니다.

@Transactional
public void deleteReview(Long reviewId) {
    Review review = reviewRepository.findByIdAndStatus(reviewId, ReviewStatus.ACTIVE)
            .orElseThrow(() -> new ApiException(ErrorCode.REVIEW_NOT_FOUND));

    reviewVisibilityRequestRepository.updateVisibilityRequestStatusByReviewId(reviewId, ReviewerResponse.AGREED);

    review.setStatus(ReviewStatus.DELETED);
    reviewRepository.save(review);
}
4.2. 결과
  • 외래 키 제약 조건 문제 해결 및 데이터 무결성 유지
  • 이메일 답신을 정확히 분석하여 리뷰 삭제 또는 상태 업데이트 기능 안정화
  • 다중 스레드 환경에서의 동시성 문제 해결
profile
전 체리 알러지가 있어요!

0개의 댓글