Senior
Comment implémenter de manière atomique la vérification de la disponibilité et la création de commandes lors de la délocalisation de la logique dans un service?
sobes.tech IA
Réponse de l'IA
Для атомарной проверки доступности и создания заказа в сервисе на 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 блокирует строку с товаром, предотвращая гонки при параллельных запросах. Вся логика в сервисе оборачивается в транзакцию, что обеспечивает атомарность операции.