ホームページ  >  記事  >  バックエンド開発  >  Golang でトランザクションを使用するにはどうすればよいですか?

Golang でトランザクションを使用するにはどうすればよいですか?

WBOY
WBOYオリジナル
2024-06-04 12:13:56846ブラウズ

Go では、トランザクション操作に Tx タイプを使用できます。トランザクションを開始するには、db.Begin() を使用します。トランザクションブロックでは、クエリや更新などのデータベース操作が実行されます。実行が成功したら、tx.Commit() を使用してトランザクションをコミットします。実際には、トランザクションにより、在庫の更新と注文の同時作成などの同時操作の一貫性が確保されます。

如何在 Golang 中使用事务?

Go でトランザクションを使用するにはどうすればよいですか?

Go では、トランザクションは、すべて成功するかすべて失敗するアトミック操作の集合です。これらは、特に複数の同時操作がデータ破損を引き起こす可能性がある状況で、データベース操作の整合性を確保するために使用されます。

Go のトランザクションは、database/sqlTx タイプで表されます。トランザクションを開始するには、次の手順を実行します。 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
}

トランザクション ブロックでは、任意のデータベース操作を実行できます。たとえば、次のコードはテーブルからレコードを選択し、新しい値で更新します。
    rrreee
  1. すべての操作が正常に実行された後、tx.Commit() を使用してトランザクションをコミットできます。 :
  2. rrreee

    実際的なケース

  3. products テーブルと orders テーブルを含むオンライン ストア データベースを考えてみましょう。次のことを行うトランザクションを作成したいと考えています:

製品に十分な在庫があるかどうかを確認します。

🎜在庫がある場合、商品の在庫を差し引いて注文が作成されます。 🎜🎜rrreee🎜トランザクションを使用することで、同じ商品から在庫を減らそうとする複数の同時注文がある場合でも、ストアの在庫が常に正確であることが保証されます。 🎜

以上がGolang でトランザクションを使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。