카테고리 없음
Plus_week(Trouble Shooting)
Twisted
2024. 12. 19. 18:01
1. 문제 정의
TODO.1 트랜잭션의 이해를 수행하던중 개선 조건에 맞춰 작동시키기 위해 @Transctional 어노테이션을 이용하였는데 rentalLogService.save에서 RuntimeException이 계속하여 발생하는 현상을 발견
해당 기존 코드 - ( ReservationService.java 일부 )
// TODO: 1. 트랜잭션 이해
public void createReservation(Long itemId, Long userId, LocalDateTime startAt, LocalDateTime endAt) {
// 쉽게 데이터를 생성하려면 아래 유효성검사 주석 처리
List<Reservation> haveReservations = reservationRepository.findConflictingReservations(itemId, startAt, endAt);
if(!haveReservations.isEmpty()) {
throw new ReservationConflictException("해당 물건은 이미 그 시간에 예약이 있습니다.");
}
Item item = itemRepository.findByIdOrElseThrow(itemId);
User user = userRepository.findByIdOrElseThrow(userId);
Reservation reservation = new Reservation(item, user, ReservationStatus.PENDING, startAt, endAt);
Reservation savedReservation = reservationRepository.save(reservation);
RentalLog rentalLog = new RentalLog(savedReservation, "로그 메세지", "CREATE");
rentalLogService.save(rentalLog);
}
해당 메서드의 흐름을 살펴보면
1. 각각의 아이템과 유저 객체를 찾아와 예약을 생성하여 저장
2. 예약을 이용하여 rentalLog를 저장
3. Exception이 일어나는경우 Transcational어노테이션에 의해 기존 상태로 되돌아감
기존의 코드는 위와 같은 형태를 가지고 있었다.
2. 원인
진짜 뭘까? 라고 생각했다. 한눈에 봐도 문제가 없었기 때문이다.
rentalLogService.save(rentalLog);
이 코드만 봐서는 RuntimeException이 발생할 이유가 없다
3. 해결방안
저 save가 어떻게 되어있을까 한번 살펴 보았다.
@Transactional
public void save(RentalLog rentalLog) {
rentalLogRepository.save(rentalLog);
if (rentalLog != null) {
throw new RuntimeException();
}
}
허허.. if안에 조건으로 rentalLog가 있는경우 RuntimeException이 발생하도록 되어있다.
그냥 무조건 발생할 수 밖에 없는 것이었다...
수정된 메서드
@Transactional
public void save(RentalLog rentalLog) {
rentalLogRepository.save(rentalLog);
if (rentalLog == null) {
throw new RuntimeException();
}
}
rentalLog의 값이 Null인 경우에만 RuntimeException이 발생하도록 수정해 주었다.
4. 테스트
@Transactional
public void save(RentalLog rentalLog) {
rentalLogRepository.save(rentalLog);
if (rentalLog == null) {
throw new RuntimeException();
}
}
public void createReservation(Long itemId, Long userId, LocalDateTime startAt, LocalDateTime endAt) {
// 쉽게 데이터를 생성하려면 아래 유효성검사 주석 처리
List<Reservation> haveReservations = reservationRepository.findConflictingReservations(itemId, startAt, endAt);
if(!haveReservations.isEmpty()) {
throw new ReservationConflictException("해당 물건은 이미 그 시간에 예약이 있습니다.");
}
Item item = itemRepository.findByIdOrElseThrow(itemId);
User user = userRepository.findByIdOrElseThrow(userId);
Reservation reservation = new Reservation(item, user, ReservationStatus.PENDING, startAt, endAt);
Reservation savedReservation = reservationRepository.save(reservation);
RentalLog rentalLog = new RentalLog(savedReservation, "로그 메세지", "CREATE");
rentalLogService.save(rentalLog); //RentalLogService의 save메서드의 조건 확인
}
이렇게 수정된 두개의 블럭을 이용하여 다시 실행을 해보니 RuntimeException이 발생하지 않았다
5. 결론
개선 글만 보고 너무 안일하게 생각했던게 잘못이다.. 현재 조건 등등 전체 글을 모두 읽어보자..