Maison  >  Article  >  développement back-end  >  Comment utiliser les transactions dans Golang ?

Comment utiliser les transactions dans Golang ?

WBOY
WBOYoriginal
2024-06-04 12:13:56790parcourir

Dans Go, vous pouvez utiliser le type Tx pour les opérations de transaction. Pour démarrer une transaction, utilisez db.Begin(). Dans le bloc de transaction, les opérations de base de données telles que les requêtes et les mises à jour sont effectuées. Après une exécution réussie, utilisez tx.Commit() pour valider la transaction. En pratique, les transactions garantissent la cohérence des opérations simultanées, telles que la mise à jour des stocks et la création simultanée de commandes.

如何在 Golang 中使用事务?

Comment utiliser les transactions dans Go ?

Dans Go, une transaction est un ensemble d'opérations atomiques qui réussissent toutes ou échouent toutes. Ils sont utilisés pour garantir l'intégrité des opérations de base de données, en particulier dans les situations où plusieurs opérations simultanées pourraient entraîner une corruption des données.

Les transactions en Go sont représentées par le type Tx dans database/sql. Pour démarrer une transaction, procédez comme suit : database/sql 中的 Tx 类型表示。要开始一个事务,请执行以下操作:

tx, err := db.Begin()
if err != nil {
    return fmt.Errorf("failed to begin transaction: %w", err)
}

在事务块中,您可以执行任何数据库操作。例如,以下代码从表中选择一条记录并将其更新为新值:

var id, version int
if err := tx.QueryRow("SELECT id, version FROM example WHERE name = ?", "foo").Scan(&id, &version); err != nil {
    return fmt.Errorf("failed to select: %w", err)
}

result, err := tx.Exec("UPDATE example SET version = ? WHERE id = ? AND version = ?", version+1, id, version)
if err != nil {
    return fmt.Errorf("failed to update: %w", err)
}

在所有操作成功执行后,您可以使用 tx.Commit() 提交事务:

if err := tx.Commit(); err != nil {
    // 放弃事务
    if err := tx.Rollback(); err != nil {
        return fmt.Errorf("failed to rollback transaction: %w", err)
    }
    return fmt.Errorf("failed to commit transaction: %w", err)
}

实战案例

考虑一个网上商店的数据库,该数据库包括一个 products 表和一个 orders

func CreateOrder(db *sql.DB, productID int, quantity int) error {
    tx, err := db.Begin()
    if err != nil {
        return fmt.Errorf("failed to begin transaction: %w", err)
    }

    var stock int
    if err := tx.QueryRow("SELECT stock FROM products WHERE id = ?", productID).Scan(&stock); err != nil {
        return fmt.Errorf("failed to select: %w", err)
    }

    if stock < quantity {
        return tx.Rollback() // 放弃事务,因为没有足够的库存
    }

    if _, err := tx.Exec("UPDATE products SET stock = ? WHERE id = ?", stock-quantity, productID); err != nil {
        return fmt.Errorf("failed to update: %w", err)
    }

    if _, err := tx.Exec("INSERT INTO orders (product_id, quantity) VALUES (?, ?)", productID, quantity); err != nil {
        return fmt.Errorf("failed to insert: %w", err)
    }

    if err := tx.Commit(); err != nil {
        return fmt.Errorf("failed to commit transaction: %w", err)
    }

    return nil
}

Dans le bloc de transaction, vous pouvez effectuer n'importe quelle opération de base de données. Par exemple, le code suivant sélectionne un enregistrement de la table et le met à jour avec une nouvelle valeur :
    rrreee
  1. Une fois toutes les opérations exécutées avec succès, vous pouvez utiliser tx.Commit() pour valider la transaction. :
  2. rrreee

    Cas pratique

  3. Considérons une base de données de boutique en ligne, qui comprend une table produits et une table commandes. Nous souhaitons créer une transaction pour effectuer les opérations suivantes :

Vérifier si un produit a suffisamment de stock.

🎜S'il y a du stock, le stock du produit est déduit et une commande est créée. 🎜🎜rrreee🎜En utilisant les transactions, nous garantissons que l'inventaire du magasin est toujours exact, même s'il y a plusieurs commandes simultanées essayant de soustraire l'inventaire du même produit. 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn