Senior
Hoe implementeer je atomair de controle van beschikbaarheid en het aanmaken van een bestelling bij het uitbesteden van de logica naar een service?
sobes.tech AI
Antwoord van AI
Для атомарной проверки доступности и создания заказа в сервисе на Go обычно используют транзакции базы данных. В рамках одной транзакции сначала проверяется доступность (например, наличие товара на складе), затем создаётся заказ. Если что-то идёт не так — транзакция откатывается, что гарантирует консистентность данных.
Пример с использованием базы данных и пакета database/sql:
func CreateOrderIfAvailable(db *sql.DB, productID int, quantity int, userID int) error {
tx, err := db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
var available int
err = tx.QueryRow("SELECT stock FROM products WHERE id = ? FOR UPDATE", productID).Scan(&available)
if err != nil {
return err
}
if available < quantity {
return fmt.Errorf("not enough stock")
}
_, err = tx.Exec("UPDATE products SET stock = stock - ? WHERE id = ?", quantity, productID)
if err != nil {
return err
}
_, err = tx.Exec("INSERT INTO orders (user_id, product_id, quantity) VALUES (?, ?, ?)", userID, productID, quantity)
if err != nil {
return err
}
return tx.Commit()
}
Здесь FOR UPDATE блокирует строку с товаром, предотвращая гонки при параллельных запросах. Вся логика в сервисе оборачивается в транзакцию, что обеспечивает атомарность операции.