Назад к вопросам
СБЕР
Senior
5
Два пользователя одновременно покупают билет на одно место в театре. Как гарантировать, что место достанется только одному?
Компании, где спрашивали
Ответ от нейросети
sobes.tech AI
Чтобы гарантировать, что два пользователя не смогут одновременно купить одно и то же место, нужно обеспечить атомарность операции бронирования. В Java это можно сделать несколькими способами:
-
Синхронизация на уровне приложения:
- Использовать synchronized-блок или ReentrantLock, чтобы только один поток мог проверить и забронировать место в один момент времени.
-
Использование транзакций и блокировок на уровне базы данных:
- В базе данных, где хранится информация о местах, использовать транзакцию с блокировкой записи (например, SELECT ... FOR UPDATE).
- При попытке забронировать место, транзакция проверяет, свободно ли оно, и если да — помечает как занятое.
- Если два запроса идут одновременно, один из них заблокирует запись, второй будет ждать или получит ошибку.
-
Оптимистичная блокировка:
- Использовать версионность записи (например, поле version).
- При обновлении проверять, что версия не изменилась с момента чтения.
- Если изменилась — повторить попытку.
Пример с synchronized:
public class Theater {
private final Set<Integer> bookedSeats = new HashSet<>();
public synchronized boolean bookSeat(int seatNumber) {
if (bookedSeats.contains(seatNumber)) {
return false; // уже занято
} else {
bookedSeats.add(seatNumber);
return true; // успешно забронировано
}
}
}
В реальных системах предпочтительнее использовать транзакции базы данных, так как они обеспечивают согласованность данных при масштабировании и работе нескольких приложений.