如何在 Golang 中使用事务?

在 go 中,可以使用 tx 类型进行事务操作。要开启事务,请使用 db.begin()。在事务块中,执行数据库操作,如查询、更新。执行成功后,使用 tx.commit() 提交事务。在实战中,事务可确保并发操作的一致性,如同时更新库存和创

在 go 中,可以使用 tx 类型进行事务操作。要开启事务,请使用 db.begin()。在事务块中,执行数据库操作,如查询、更新。执行成功后,使用 tx.commit() 提交事务。在实战中,事务可确保并发操作的一致性,如同时更新库存和创建订单。

如何在 Golang 中使用事务?

如何在 Go 中使用事务?

在 Go 中,事务是一组原子操作的集合,要么全部成功,要么全部失败。它们用于确保数据库操作的完整性,尤其是在多个并发操作可能导致数据损坏的情况下。

Go 中的事务由 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 表。我们希望创建一个事务来执行以下操作:

  1. 检查产品是否有足够的库存。
  2. 如果有库存,则扣除产品的库存并创建订单。
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
}

登录后复制

通过使用事务,我们确保了商店的库存始终准确,即使有多个并发订单尝试从同一个产品减去库存。

以上就是如何在 Golang 中使用事务?的详细内容,更多请关注叮当号网其它相关文章!

文章来自互联网,只做分享使用。发布者:weapp,转转请注明出处:https://www.dingdanghao.com/article/483544.html

(0)
上一篇 2024-05-14 14:01
下一篇 2024-05-14 14:40

相关推荐

联系我们

在线咨询: QQ交谈

邮件:442814395@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信公众号