withdrawals table의 저장되는 컬럼의 user_id에 null값이 찍힘
Withdrawal withdrawal = Withdrawal.builder()
.id(targetUser.getId())
.requestTime(now)
.scheduledDeletionTime(scheduledDeletionTime)
.status(WithdrawalStatusEnum.PENDING) // 탈퇴 상태를 대기 중으로 설정
.build();
LocalDateTime now = LocalDateTime.now();
LocalDateTime scheduledDeletionTime = now.plusMinutes(1);
Withdrawal withdrawal = Withdrawal.builder()
.user(targetUser) // 사용자 엔티티를 설정
.requestTime(now)
.scheduledDeletionTime(scheduledDeletionTime)
.status(WithdrawalStatusEnum.PENDING)
.build();withdrawals table의 정보와 users table의 정보가 여전히 삭제되지 않음
withdrawals table에 있는 정보가 만료기간이 다 되면 삭제될 때 users table에 있는 같은 정보도 사라지게 만들려면….
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Withdrawal> withdrawals = new ArrayList<>();@ManyToOne
@JoinColumn(name = "user_id")
private User user;@Scheduled(fixedRate = 60000) 스케줄링이 작동되는 주기의 시간과
LocalDateTime standardTime = LocalDateTime.now().minusMinutes(5); // 현재 시간보다 n시간 전에 있었던 것을 삭제 -> n시간이 유예기간 회원 탈퇴와 관련된(다른 기능도) 기능의 정보를 담아주는 시간이 별개

wuthdrawals table에서 삭제되면 users table에서도 삭제 해야하는데, 딱히 연관 관계의 문제는 아니었다!
→ @ManyToOne 안에 cascade = CascadeType.REMOVE를 주면 삭제할 수 있지만, 적합하지 않음
- 해결 방법 : 스케줄러에서 userRepository를 불러와서 직접 삭제해주어야 한다
@Scheduled(fixedRate = 600000) // 매 분마다 스케줄링가 돌아야 삭제가 된다!
@Scheduled(fixedRate = 600000)가 돌아가지 않고 LocalDateTime standardTime = LocalDateTime.now().minusMinutes(5);의 유예기간이 끝나도 삭제되지 않는다
- 유예기간은 30일로 하되, 그 처리하는 기간은 30일 보다 더 적은 날짜로 일을 시켜야 유예기간 30일이 지켜진다
- ex) 유예기간은 30일, 스케줄드는 매일 자정!
해야 할 것
public static class Authority {
public static final String USER = "ROLE_USER";
public static final String ADMIN = "ROLE_ADMIN";
}
enum 역할 추가 - DENY
UserService - public ResponseEntity withdrawUser(User user)에 @Transactional를 걸어주고 enum 역할의 DENY로 변경할 수 있도록! → 팀장님이 도와주고… 완료
withdrawal table의 expire_time 시간 나타내기
// Withdrawal 엔티티를 생성하고 예정 탈퇴 시간을 설정
LocalDateTime requestTime = LocalDateTime.now();
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(1);
// 이미 탈퇴 진행 중인지 확인
Optional<Withdrawal> existingWithdrawal = withdrawalRepository.findByUserId(targetUser.getId());
if (existingWithdrawal.isPresent()) {
return ResponseEntity.badRequest().body("이미 탈퇴 진행 중입니다.");
} else{
Withdrawal withdrawal = Withdrawal.builder()
.user(targetUser) // 사용자 엔티티를 설정
.requestTime(requestTime)
.expireTime(expireTime)
.build();
withdrawalRepository.save(withdrawal); // Withdrawal 정보 저장
시간 계산을 볼 수 있도록 log 추가
log.info("현재 시간: {}", currentDateTime);
log.info("탈퇴 요청: {}", standardTime);
log.info("현재 시간 - 탈퇴 요청 = 탈퇴 유예 기간");
스케줄러 하루에 3번, 유예 기간 7일으로 설정하기!
@Scheduled(cron = "0 0 6,23 * * *") 시간 피하기(혹시 모를 과부화, 트래픽 대비)Scheduled 어노테이션을 사용하여 스케줄러의 시간을 설정
고정 속도로 스케줄링 (fixedRate):
fixedRate 속성을 사용하여 일정한 간격으로 작업을 실행할 수 있습니다. 예를 들어, 아래의 코드는 1분마다 작업을 실행합니다.javaCopy code
@Scheduled(fixedRate = 60000)
public void myScheduledTask() {
// 작업 내용
}
고정 지연 시간으로 스케줄링 (fixedDelay):
fixedDelay 속성을 사용하여 이전 작업이 완료된 후 일정한 지연 시간 후에 작업을 실행할 수 있습니다. 예를 들어, 아래의 코드는 작업이 완료된 후 1분 후에 다시 작업을 실행합니다.javaCopy code
@Scheduled(fixedDelay = 60000)
public void myScheduledTask() {
// 작업 내용
}
Cron 표현식 사용:
javaCopy code
@Scheduled(cron = "0 0 2 * * ?")
public void myScheduledTask() {
// 작업 내용
}
?는 "일자를 지정하지 않음"을 나타내는 특수한 값입니다. Cron 표현식은 초, 분, 시, 일, 월, 주(요일)을 지정하는데 사용됩니다. ?는 이 중 "일" 필드를 나타내며, 이 필드를 표시하지 않음을 의미합니다. ?를 사용하는 이유는 몇몇 Cron 표현식에서 "일" 필드와 "요일" 필드를 동시에 지정할 때 유용합니다. 예를 들어, 매주 월요일에 작업을 실행하려면 다음과 같이 Cron 표현식을 사용할 수 있습니다:kotlinCopy code
@Scheduled(cron = "0 0 * * MON ?")
이렇게 하면 "일" 필드는 ?로 지정되어 있으며, "요일" 필드는 MON으로 지정되어 월요일에만 작업이 실행됩니다. 일과 요일 중 하나만 지정하고 나머지는 ?로 표시하여 각각의 필드를 독립적으로 조절할 수 있습니다.@Scheduled(cron = "0 0 6,23 * * *")는 Spring Framework에서 사용되는 Cron 표현식으로, 주어진 시간에 작업을 실행하는 방식을 나타냅니다. 이 표현식은 다음과 같이 해석됩니다:초 (Seconds): 0
분 (Minutes): 0
시 (Hours): 6 또는 23
일 (Day of month): 모든 날짜
월 (Month): 모든 달
요일 (Day of week): 모든 요일
따라서 이 Cron 표현식은 매일 오전 6시와 오후 11시에 작업을 실행하도록 설정됩니다. 즉, 하루에 두 번 작업이 실행됩니다.
초기 지연 시간 설정:
initialDelay 속성을 사용하여 스케줄러를 시작할 때 초기 지연 시간을 설정할 수 있습니다. 예를 들어, 스케줄러를 시작한 후 30초를 기다린 후에 작업을 실행하려면 다음과 같이 할 수 있습니다.javaCopy code
@Scheduled(initialDelay = 30000, fixedRate = 60000)
public void myScheduledTask() {
// 작업 내용
}
확인하기!
시간 맞추기
UserService - public ResponseEntity withdrawUser(User user)
// Withdrawal 엔티티를 생성하고 예정 탈퇴 시간을 설정
LocalDateTime requestTime = LocalDateTime.now();
LocalDateTime expireTime = LocalDateTime.now().plusDays(7);
// 이미 탈퇴 진행 중인지 확인
Optional<Withdrawal> existingWithdrawal = withdrawalRepository.findByUserId(targetUser.getId());
if (existingWithdrawal.isPresent()) {
return ResponseEntity.badRequest().body("이미 탈퇴 진행 중입니다.");
} else{
Withdrawal withdrawal = Withdrawal.builder()
.user(targetUser) // 사용자 엔티티를 설정
.requestTime(requestTime)
.expireTime(expireTime)
.build();
withdrawalRepository.save(withdrawal); // Withdrawal 정보 저장
public class WithdrawalScheduler
LocalDateTime standardTime = LocalDateTime.now().minusDays(7);
withdrawals table

스케줄러
Redis → Scheduled…. 헤매고 어지럽고 어려웠던 기능이 끝났다
다음거는… 아마도 레디스를 중점으로 알람 기능! 소켓도 필요!