[Spring] Schedular 이용하여 soft, hard delete 구현 (@Scheduled)

icebox127·2026년 5월 1일

졸업 프로젝트로 깃허브 분석 & 면접 대비 & 커뮤니티 기능의 서비스를 제작 중이다.
이때 탈퇴 시, 서버 용량 상 분석 & 면접 내용은 삭제하여야하나, 커뮤니티 글은 남겨야 한다. 또한, 탈퇴 후 7일 이내에는 재가입(복구) 가능하도록 구현하였다.

  • 기본 상태 : ACTIVATE
  • 처음 탈퇴 시 : INAVTIVATE (Soft delete, 일주일 내 재가입 시 계정복구 가능)
  • 탈퇴 후 일주일 뒤 : DELETE (Hard delete, 커뮤니티 제외 개인 기록 삭제, 복구 불가)

1. Soft Delete

soft delete는 실제 db에서 삭제하진 않으나, 비활성화 처리를 하는 것이다.
회원 정보 중 status만 INACTIVATE로 변경한다.

 public void inactivateMember() {
    this.status = Status.INACTIVATE;
    this.deletedAt = LocalDateTime.now();
}

2. Hard Delete

실제로 db에서 데이터를 삭제한다. soft delete로 비활성화 처리 후 7일이 지나면, 회원의 분석&면접 기록을 삭제 + 회원 정보를 null로 비워둔다. (커뮤니티 글이 회원 엔터티를 참조하기 때문에 회원 행을 삭제하진 않지만, 정보는 없애야 함)

특히 이메일과 소셜 id 등 추후 가입 시 중복 사용될 가능성이 있는 부분/unique 설정된 내용은 무조건 null처리 해야한다.

public void deleteMember() {
    this.status = Status.DELETE;
    this.nickname = "탈퇴한 사용자"+id;
    this.socialUid = null;
    this.email = null;
    this.profileImage = null;
    this.githubId = null;
    this.githubName = null;
    interestStacks.clear();
    reports.clear();
}

3. Schedular 사용

inactivateMember()는 사용자가 회원탈퇴 요청을 했을 때 사용하면 된다.
하지만 그로부터 7일 뒤, 자동으로 deleteMember()처리는 어떻게 하는걸까?

@Transactional
public void withdraw(Member currentMember) {
   Member member = memberRepository.findById(currentMember.getId())
                .orElseThrow(() -> new MemberException(MemberErrorCode.NOT_FOUND));
   member.inactivateMember(); // 비활성화
}

이럴 때 쓸 수 있는게 스케줄러다.
스프링 부트에선 @Scheduled을 사용하여 스케줄러를 구현할 수 있다.

3.1 Application 설정

jpa, async와 마찬가지로 스케줄러도 사용하려면 application 설정을 해줘야한다.

@SpringBootApplication
@EnableScheduling // 추가
public class GitTurlApplication {

	public static void main(String[] args) {
		SpringApplication.run(GitTurlApplication.class, args);
	}

}

3.2 Schedular 구현

@Component
@RequiredArgsConstructor
public class Schedular {
    private final MemberRepository memberRepository;

    @Scheduled(cron = "0 45 17 * * *")
    public void deleteInactiveMembers() {

        LocalDateTime standard = LocalDateTime.now().minusDays(7);

        List<Member> members =
                memberRepository
                        .findAllByStatusAndDeletedAtBefore(
                                Status.INACTIVATE,
                                standard
                        );

        for (Member m : members) {
            m.deleteMember();
        }
    }
}

실행 결과

Soft Delete



요청 시 데이터는 그대로 남기고 상태만 INACTIVATE로 변경되었다.

Hard Delete

지금까지 테스트 한 데이터를 다 날릴 순 없어서, 임의로 테스트 계정 + 기타정보를 만들었다. 다음 회원과, 연관 관계인 데이터를 1개씩 생성


그 다음, 시간을 변경 시킨 후 서버를 실행 시킨다.

// 스케줄러 작동시간 현재로 변경
@Scheduled(cron = "0 45 17 * * *")


스케줄러가 작동하여 삭제 되었다.

참고 자료

https://velog.io/@developer_khj/Spring-Boot-Scheduler-Scheduled

profile
감자의 공부기록🥔

0개의 댓글