개인 프로젝트 고민 - 예약 기능(1)

헨도·2025년 1월 3일
0

SpringBoot

목록 보기
21/23
post-thumbnail

스프링을 시작한 후 개인 프로젝트로 풋살장 예약 API를 만들어보고 싶다는 생각으로 플젝을 진행 중이였는데... 풋살장 예약 기능을 어떻게 만들지 고민했다.

고민

풋살장 예약 기능

  1. 일정 간격(3일 ~ 7일) 동안 예약을 열어둔다.
  2. 특정일에 맞춰 2시간 간격으로 풋살장을 예약할 수 있다.
    • Ex. '2025-01-03' 16~18시
  3. 예약 조회 시, 예약이 가능한 블록만 조회 가능하다.

나의 방식

구장 조회 시 예약이 가능한 시간들도 같이 조회되기 때문에 일정 시간대에 3일 간격의 예약 블록을 미리 만들어두자.

  • 예약 가능한 시간들은 ReserveTime 값의 Enum으로 만들었다.
  1. 매일 오전 9시 스케줄러를 이용
  2. 예약 블록의 날짜 컬럼에 오늘 날짜가 있는지 검사
	LocalDate today = LocalDate.now();
    LocalDate todayAfter3 = today.plusDays(3);
	log.info("today: {} - todayAfter3: {}", today, todayAfter3);

3-1. 오늘 날짜가 있을 시, 스케줄러 종료

	if (reserveRepository.existsReserveSlot(today, todayAfter3)) {
		log.error("3일 내 예약이 가능한 슬롯이 존재합니다.");
		return;
	}

3-2. 오늘 날짜가 없을 시, 구장 전체 정보를 가져온 후 오늘 ~ 오늘 +3일 예약 블록 만들기

	List<Stadium> stadiums = stadiumRepository.findAllByIsUsedIsTrue();

    for (int i = 0; i <= 3; i++) {
	    LocalDate reservationDate = today.plusDays(i);

	    for (Stadium stadium : stadiums) {
            for (ReserveTime time : ReserveTime.values()) {
            	Reserve newReserve = Reserve.builder()
                	.stadium(stadium)
                    .reserveDate(reservationDate)
                    .reserveTime(time)
                    .available(true)
                    .status(Status.AVAILABLE)
                    .createdAt(LocalDateTime.now())
                    .build();

            	reserveRepository.save(newReserve);
			}
		}
    }
  1. 예약이 안된 블록이 있을 경우, DB에 가비지 데이터로 남으니 삭제한다.
	// 지난 날짜 + 예약이 안된 블록은 삭제하기
    reserveRepository.deleteReserve(today);
    log.info("예약이 안된 블록 삭제");

위 과정을 거치면 Reserve 테이블에 예약이 가능한 블록들이 생긴다.

그 후 만들어진 블록에 사용자의 id 와 상태를 update 를 하여 예약이 완료되는 시스템으로 구축했다.

위 방식은 내 방식이지만 조금 이상하다는 느낌이 들어 차장님께 여쭤봤고 차장님께서는 예약을 update 로 하는 방법도 있지만, insert를 사용하는 방법이 좋다고 하시면서 피드백을 해주셨다.

  • 여러 사용자가 동시에 예약을 신청했을 때, 동시성을 처리하기에는 Update 보다 Insert 가 더 수월하다.
  • Insert 는 새로운 이벤트를 만드는 것이기 때문에 기존 데이터를 사용하여 수정하는 Update 보다 실수로 덮어쓰는 사고를 미리 방지할 수 있다.

이러한 이유 때문에 Update -> Insert 로 코드를 수정한다.

profile
Junior Backend Developer

0개의 댓글