it-source

시간 충돌 없이 예약 추가

criticalcode 2023. 10. 8. 09:57
반응형

시간 충돌 없이 예약 추가

저는 각 사용자가 원하는 시간에 방을 예약할 수는 있지만 예약을 추가할 수 없는 예약 시스템(PHP, MariaDB, Symfony, Doctrine 사용)을 개발합니다. 같은 방에 다른 방과 겹칩니다.따라서 매번 INSERT를 하기 전에 SELECT를 수행하여 예약 가능 시간을 확인합니다.

// ReservationRepository.php
public function getConflictIds(Reservation $rsvn, int $limit = 1): array
{
    return $this->createQueryBuilder('rsvn')
        ->select('rsvn.id')
        ->where('rsvn.room = :roomId')
        ->andWhere(':beginTime < rsvn.end_time')
        ->andWhere(':endTime > rsvn.begin_time')
        ->setMaxResults($limit)
        ->setParameters([
            'roomId' => $rsvn->getRoom()->getId(),
            'beginTime' => $rsvn->getBeginTime(),
            'endTime' => $rsvn->getEndTime(),
        ])
        ->getQuery()->getResult();
}
// ReservationController.php
$em = $this->getDoctrine()->getManager();
$repo = $this->getDoctrine()->getRepository(Reservation::class);
$em->beginTransaction();
try {
    if (count($repo->getConflictIds($rsvn)) > 0) {
        throw new Exception();
    }
    $em->persist($rsvn);
    $em->flush();
    $em->commit();
    // redirect
} catch (\Exception $e) {
    $em->rollback();
}

첫번째 사용자는 예약 가능 여부를 확인하고(SELECT), 첫번째 사용자는 INSERT를 수행하기 전에 두번째 사용자도 확인하기 때문에 중복될 수 있는 예약이 추가될 것 같습니다.

첫 번째 사용자가 거래를 종료하기 전에 다른 사용자의 가용성 확인(SELECT)을 차단하는 것이 가장 좋을 것으로 생각하지만, 저는 다른 해결책에 열려 있습니다.네 가지 옵션을 고려하고 있는데, 이 경우 어떤 것이 가장 좋을지 모르겠습니다.

  1. 잠금 테이블 예약 기록;
  2. ID가 = ?인 룸에서 *를 선택하여 업데이트합니다.
  3. 트랜잭션 격리 수준 직렬화 AB 설정LE;
  4. 삽입 후 SELECT를 수행하고 추가된 행 외에 충돌을 일으키는 다른 행이 있을 경우 롤백을 수행합니다.

어떤 제안이든 감사합니다.

언급URL : https://stackoverflow.com/questions/64215643/adding-reservations-without-time-conflicts

반응형