Sobes.tech
Назад к вопросам
Senior
5

Два пользователя одновременно покупают билет на одно место в театре. Как гарантировать, что место достанется только одному?

Компании, где спрашивали
СБЕРСБЕР

Ответ от нейросети

sobes.tech AI

Чтобы гарантировать, что два пользователя не смогут одновременно купить одно и то же место, нужно обеспечить атомарность операции бронирования. В Java это можно сделать несколькими способами:

  1. Синхронизация на уровне приложения:

    • Использовать synchronized-блок или ReentrantLock, чтобы только один поток мог проверить и забронировать место в один момент времени.
  2. Использование транзакций и блокировок на уровне базы данных:

    • В базе данных, где хранится информация о местах, использовать транзакцию с блокировкой записи (например, SELECT ... FOR UPDATE).
    • При попытке забронировать место, транзакция проверяет, свободно ли оно, и если да — помечает как занятое.
    • Если два запроса идут одновременно, один из них заблокирует запись, второй будет ждать или получит ошибку.
  3. Оптимистичная блокировка:

    • Использовать версионность записи (например, поле 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; // успешно забронировано
        }
    }
}

В реальных системах предпочтительнее использовать транзакции базы данных, так как они обеспечивают согласованность данных при масштабировании и работе нескольких приложений.