Lv. 3 Transaction 심화
조건
- 매니저 등록 요청을 기록하는 로그 테이블을 만들어주세요.
- 매니저 등록과는 별개로 로그 테이블에는 항상 요청 로그가 남아야 해요.
- 매니저 등록은 실패할 수 있지만, 로그는 반드시 저장되어야 합니다.
- 로그 생성 시간은 반드시 필요합니다.
- 그 외 로그에 들어가는 내용은 원하는 정보를 자유롭게 넣어주세요.
구현 전략
- Log 엔티티 & Repository 생성
- 로그 저장용 서비스 생성
@Transactional(propagation = Propagation.REQUIRES_NEW) 사용
- 매니저 등록을 수행 하는 서비스에서 로그 저장 호출
1. Log 엔티티 설계
@Entity
@Setter
@Table(name = "log")
public class Log {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;
private String action;
private String details;
private LocalDateTime createdAt;
@PrePersist
public void prePersist() {
this.createdAt = LocalDateTime.now();
}
}
2. Repository 설계
public interface LogRepository extends JpaRepository<Log, Long> {
}
3. Service 설계
@Service
public class LogService {
private final LogRepository logRepository;
public LogService(LogRepository logRepository) {
this.logRepository = logRepository;
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveLog(String action, String details) {
Log log = new Log();
log.setAction(action);
log.setDetails(details);
logRepository.save(log);
}
}
4. 매니저 등록 서비스에 try-finally문 추가
try{
User user = User.fromAuthUser(authUser);
Todo todo = todoRepository.findById(todoId)
.orElseThrow(() -> new InvalidRequestException("Todo not found"));
if (todo.getUser() == null || !ObjectUtils.nullSafeEquals(user.getId(), todo.getUser().getId())) {
throw new InvalidRequestException("담당자를 등록하려고 하는 유저가 유효하지 않거나, 일정을 만든 유저가 아닙니다.");
}
User managerUser = userRepository.findById(managerSaveRequest.getManagerUserId())
.orElseThrow(() -> new InvalidRequestException("등록하려고 하는 담당자 유저가 존재하지 않습니다."));
if (ObjectUtils.nullSafeEquals(user.getId(), managerUser.getId())) {
throw new InvalidRequestException("일정 작성자는 본인을 담당자로 등록할 수 없습니다.");
}
Manager newManagerUser = new Manager(managerUser, todo);
Manager savedManagerUser = managerRepository.save(newManagerUser);
return new ManagerSaveResponse(
savedManagerUser.getId(),
new UserResponse(managerUser.getId(), managerUser.getEmail())
);
} catch (Exception e) {
throw e;
} finally {
logService.saveLog(
"매니저 요청", "userId: " + authUser.getId() + ", todoId: " + todoId + ", managerUserId: " + managerSaveRequest.getManagerUserId()
);
}