Skip to content

Conversation

@hisonghy
Copy link
Contributor

@hisonghy hisonghy commented Nov 3, 2025

📌 작업 내용 및 특이사항

  • 서비스에서 데이터 삭제 과정이 논리 삭제 -> 물리 삭제 흐름으로 진행되는데, 테스트 편리성을 위해 API 요청 즉시 물리 삭제 처리되도록 기능을 구현했습니다.

✅ S3 스토리지 retry, time-out 설정 추가

  • 이미지 관련 작업 중 예기치 못한 IO/네트워크 오류 등으로 재시도가 필요한 상황이 생길 수도 있어 Retry(재시도)를 설정했습니다.
  • S3 네트워크 지연이나 응답이 정체되는 상황에서 무한 대기에 빠지지 않고 시스템의 안정성을 높이기 위해 time-out(타임아웃)을 설정했습니다.
  • application-storage.yml 파일에 S3 retry, time-out 설정을 추가했습니다.
  • S3Config에서 S3Client 빈을 등록하는 부분에 retry, time-out 옵션을 설정했습니다.
  • Retry(재시도)는 코드 상으로 직접 구현하거나 Spring Retry 같은 라이브러리를 활용할 수도 있지만, 코드가 더 복잡해지고 학습하는 데 시간이 걸릴 것 같아 AWS SDK V2가 기본으로 제공하는 재시도와 타임아웃 설정 옵션을 사용했습니다.

✅ 멤버 즉시 삭제 기능 구현 (CASCADE)

  • 로그인된 회원의 ID를 기반으로 관련된 모든 데이터를 삭제하는 기능을 추가했습니다.
  • 자식 데이터부터 순차적으로 삭제하고, 마지막에 제일 최상위 데이터인 멤버 모델이 삭제되도록 구현했습니다.
  • Member, StudyLog, TripReport는 이미지를 보유하고 있는데, 관련된 실제 이미지를 함께 삭제하기 위해 트랜잭션 기반 이벤트 처리(Transactional Event) 방식을 사용했습니다.

✅ 이벤트 기반 이미지 배치 정리 기능 추가

  • 이벤트를 활용하면서 엔티티 삭제와 이미지 정리 로직을 분리하고, 트랜잭션이 성공적으로 커밋된 이후에만 실제 이미지 삭제가 수행되도록 보장했습니다.
  • 트랜잭션 기반 이벤트 처리를 적용하지 않고, 하나의 트랜잭션 내에서 엔티티 삭제와 이미지 정리 로직을 함께 수행할 경우 문제가 발생할 수 있습니다.
    일부 이미지가 삭제된 시점에서 에러가 발생하면, 데이터베이스 변경사항은 모두 롤백되지만 S3와 같은 외부 스토리지는 이미 처리된 작업에 대한 롤백이 불가능하기 때문에 DB 데이터와 실제 스토리지 상태 간의 정합성이 불일치하는 문제가 발생할 수 있습니다.
    이를 방지하고 안정성을 높이고자 @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)를 사용했습니다.
  • 이벤트 발행은 멤버 도메인에서 처리할 수도 있지만, 이벤트 발행/이벤트 정의/구독을 모두 image.application 계층에 배치했습니다.
    이미지 정리 로직이 멤버 도메인, 멤버 삭제와 같은 행위에 종속되지 않고 이미지 정리를 중심으로 동작하기 위해서 image 모듈에 정의했습니다. 추후 다른 곳에서 이미지 정리 이벤트가 필요할 경우 재사용하거나 커스텀해서 사용할 수 있을 것 같습니다.

🌱 관련 이슈


🔍 참고사항(선택)

  • ImageService.cleanupBatch()에서 이미지 정리에 실패한 항목을 따로 저장하거나 바로 재시도하지 않고 단순히 로그만 남기도록 구현했습니다.
    이 기능이 핵심 기능이 아니라 효율적이고 빠른 테스트를 위한 보조 기능이라 이렇게 설계했는데, 추후 확장할 수도 있을 것 같습니다.
    찾아 보니 failed_deleted_image 같은 테이블을 별도로 두고 스케줄러를 기반으로 재시도하는 방법을 적용할 수도 있고,
    Outbox 패턴을 적용해 실패한 삭제 작업을 비동기로 처리하는 방식을 적용할 수도 있고,
    메트릭 수집 및 모니터링 시스템을 도입해 이미지 정리 성공률과 실패율을 추적하는 방향으로도 발전시킬 수 있다고 합니다.
    참고하면 좋을 것 같습니다!

📚 기타(선택)

* feat: 멤버 즉시 삭제 요청 API 구현
* feat: 멤버와 관련된 모든 데이터를 즉시 삭제하는 기능 구현 (Trip, Stamp, Mission, DailyGoal, DailyMission, Pomodoro, StudyLog, StudyLogDailyMission, TripReport, TripReportStudyLog, Image)
* feat: 이벤트 기반 이미지 삭제 로직 추가

* chore: S3 스토리지 설정 추가 (retry, time-out)

* test: 멤버 즉시 삭제 통합 테스트 추가
* test: 멤버와 관련된 모든 데이터를 즉시 삭제하는 단위 테스트 추가
@hisonghy hisonghy self-assigned this Nov 3, 2025
@hisonghy hisonghy added ⚙️chore 세팅 관련 ✨feature 구현, 개선 사항 관련 부분 labels Nov 3, 2025
Copy link
Contributor

@chaiminwoo0223 chaiminwoo0223 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어려운 작업하시느라 정말 고생하셨습니다. 머지 부탁드려요!

@hisonghy hisonghy merged commit f390c1a into develop Nov 4, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚙️chore 세팅 관련 ✨feature 구현, 개선 사항 관련 부분

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨[FEAT]: 회원 즉시 삭제 기능 추가

3 participants