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

Как решить проблему конкурентного бронирования при переходе на реальную базу данных?

Компании, где спрашивали
2gis2gis

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

sobes.tech AI

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

Основные подходы:

  • Оптимистичная блокировка: в таблице добавляется поле версии (version) или timestamp. При обновлении записи проверяется, что версия не изменилась с момента чтения. Если изменилась — операция откатывается и повторяется.

  • Пессимистичная блокировка: при попытке бронирования строка блокируется (например, SELECT ... FOR UPDATE), чтобы другие транзакции не могли её изменить до завершения текущей.

  • Транзакции с уровнем изоляции SERIALIZABLE: гарантируют, что параллельные транзакции выполняются как последовательные, предотвращая конфликты.

Пример с использованием пессимистичной блокировки в Go с PostgreSQL:

func BookSlot(db *sql.DB, slotID int) error {
    tx, err := db.Begin()
    if err != nil {
        return err
    }
    defer tx.Rollback()

    var available bool
    err = tx.QueryRow("SELECT available FROM slots WHERE id = $1 FOR UPDATE", slotID).Scan(&available)
    if err != nil {
        return err
    }

    if !available {
        return errors.New("слот уже забронирован")
    }

    _, err = tx.Exec("UPDATE slots SET available = false WHERE id = $1", slotID)
    if err != nil {
        return err
    }

    return tx.Commit()
}

Такой подход гарантирует, что одновременно только одна транзакция сможет забронировать слот.