#mongodb
Вопрос:
При внедрении типичной системы бронирования конференц-залов с использованием СУБД будут выполняться две операции:
-- Check for any existing bookings that overlap with the period of noon-1pm
SELECT COUNT(*) FROM bookings WHERE room_id = 123 AND
end_time > '2015-01-01 12:00' AND start_time < '2015-01-01 13:00';
-- If the previous query returned zero:
INSERT INTO bookings
(room_id, start_time, end_time, user_id)
VALUES (123, '2015-01-01 12:00', '2015-01-01 13:00', 666);
код из: Разработка приложений с интенсивным использованием данных (страница 249) — Мартин Клеппманн
И нам нужно будет установить уровень изоляции на сериализуемый, чтобы избежать случая, когда два пользователя думают, что конфликтов нет, и вставляют два конфликтующих бронирования.
Мой вопрос таков:
Предполагая, что мы моделируем каждый интервал времени бронирования как документ, как мы реализуем систему, которая может избежать конфликтных бронирований в MongoDB?
- Мне больше любопытно, как MongoDB обрабатывает параллельные транзакции.
- Допустим, я хочу разрешить пользователям бронировать любой возможный временной интервал, а не только заранее определенный временной интервал.
- Предположим, пользователь A хочет забронировать временной интервал T1, а B хочет забронировать временной интервал T2, и T1 и T2 перекрываются друг с другом. Очень возможно, что два пользователя одновременно перейдут на страницы бронирования, проверят MongoDB и не обнаружат конфликтов, и они оба решат вставить два временных интервала, которые конфликтуют друг с другом, в базу данных.
- В СУБД мы устанавливаем уровень изоляции для решения этой проблемы, как насчет MongoDB?
Комментарии:
1. Что вы имеете в виду под
And we'll need to set the isolation level to serializable
этим ?2. @MuratColyaran В СУБД мы используем уровень изоляции для контроля того, как параллельные транзакции влияют друг на друга. и в этом случае необходимо использовать сериализуемый.
Ответ №1:
Это атомарно, когда вы выполняете операцию над документом. В Монго есть транзакции, подобные тем, что есть в SQL.
Это может быть полезно; https://docs.mongodb.com/manual/core/transactions/
Комментарии:
1. но здесь я выполняю две операции: 1. проверьте, есть ли конфликтующие заказы (документы) в MongoDB 2. если нет, то вставьте бронирование (новый документ) в MongoDB Я полагаю, что эти две операции не являются атомарными?
Ответ №2:
Я не совсем уверен, что вы имеете And we'll need to set the isolation level to serializable
в виду, но я бы добавил дополнительный слой, который отправляет запрос, когда пользователь выбирает между двумя датами перед бронированием.
Итак, на стороне API. У вас должна быть конечная точка списка, которая возвращает забронированные и выбранные даты.
Ф. е:
{
"reservations": [
{
"userId": "1234567",
"startDate": "19-08-2021",
"endDate": "22-08-2021"
}
...
]
}
А на лицевой стороне вы можете показать даты между startDate
и endDates
занятыми.
И когда пользователь выбирает между двумя датами, вы можете отправить запрос с выбранными датами.
например, конечная точка-это СООБЩЕНИЕ /reservations/{roomId}/selected
Затем вы можете пометить комнату как выбранную, например, на 300 секунд.
[
{
"roomId": "1234456",
"selected": true,
"booked": false
}
...
]
Когда пользователь заплатил за номер или что-то в этом роде. Вы можете отметить забронированный номер
[
{
"roomId": "1234456",
"selected": false,
"booked": true
}
...
]
Если пользователь не произвел платеж за эти 300 секунд, вы можете перенаправить его на главный экран. И booked: false
снова пометьте комнату.
Редактировать:
Я не был уверен, что происходит isolation level
во время написания анализатора. Но поскольку я привожу вам пример, я думаю, что вы можете использовать ту же систему. Вы можете пометить номер selected: true
до тех пор, пока не будет произведена оплата
Комментарии:
1. Спасибо, но мне больше интересно, как MongoDB обрабатывает параллельные транзакции. Допустим, я хочу разрешить пользователям бронировать любой возможный временной интервал, а не только предопределенные временные интервалы, как в вашем дизайне. Предположим, пользователь A хочет забронировать временной интервал T1, а B хочет забронировать временной интервал T2, и T1 и T2 перекрываются друг с другом. Очень возможно, что два пользователя одновременно попадают на страницы бронирования и не обнаруживают конфликтов, запрашивая MongoDB, и оба они вставляют два временных интервала, которые конфликтуют друг с другом, в базу данных. В СУБД мы устанавливаем уровень изоляции для решения этой проблемы, как насчет MongoDB?
2. @JohntheTraveler Если вы добавите дополнительный слой в свой интерфейс и отметите выбранную комнату или что-то еще, вам не нужно беспокоиться о конфликтах. Потому что вы сможете проверить, выбрал ли пользователь номер, прежде чем перенаправлять его на экран оплаты.. Метод, о котором вы говорите, также может работать, но вам нужно создать новую коллекцию, модель и многое другое. Вам также нужно будет рассчитать даты в каждом месяце.. Это большая работа.