#symfony #transactions #doctrine #mariadb #locking
#symfony #транзакции #доктрина #mariadb #блокировка
Вопрос:
Я разрабатываю систему бронирования (с использованием PHP, MariaDB, Symfony и Doctrine), в которой каждый пользователь может забронировать номер в любое желаемое время, но не может добавить бронирование, которое перекрывает другое в том же номере. Поэтому перед каждой вставкой я выполняю ВЫБОР, чтобы проверить, доступно ли время резервирования.
// 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();
}
Я боюсь, что первый пользователь проверит, доступно ли резервирование (ВЫБЕРИТЕ), в то время как второй пользователь также проверит это до того, как первый пользователь выполнит ВСТАВКУ, поэтому оба они добавят заказы, которые могут перекрываться.
Я думаю, было бы лучше запретить другим пользователям проверять доступность (ВЫБРАТЬ) до того, как первая транзакция завершит транзакцию, но я открыт для других решений. Я рассматриваю четыре варианта, но я не знаю, какой из них будет лучшим в этом случае:
- БЛОКИРОВКА записи резервирования ТАБЛИЦЫ;
- ВЫБЕРИТЕ * ИЗ номеров, ГДЕ id = ? ДЛЯ ОБНОВЛЕНИЯ;
- УСТАНОВИТЕ СЕРИАЛИЗУЕМЫЙ УРОВЕНЬ ИЗОЛЯЦИИ ТРАНЗАКЦИЙ;
- Выполните SELECT после ВСТАВКИ и выполните ОТКАТ, если, кроме добавленной строки, есть еще одна, которая вызывает конфликт.
Любые предложения, спасибо