GoのSQLでトランザクションを扱う
In Go, a transaction is essentially an object that reserves a connection to the datastore.
Goにおけるトランザクションはデータストアへのコネクションを保持するオブジェクトのようなものです
TxオブジェクトはDBオブジェクトと同じAPIを持つ
気をつけること:SQL statementのBEGINやCOMMITと、GoのBegin()などを混ぜて使わないこと
実際の状態とTxの状態がinconsistentになるから
Txを使うと、1つのデータベースコネクションの中で全ての操作がおこなわれる
トランザクション以外にも、コネクションの共有が必要なものがあればTxを使うべき
DB.BeginTxには引数としてTxOptions Docを渡すことができる サンプルコード
書いてはみたけどRollback時のエラーの扱いについてidiomaticな書き方を調べたい
code:load_fixtures.go
package main
import (
"database/sql"
)
type users struct {
id int
name string
}
func loadFixture(db *sql.DB) error {
tx, err := db.Begin()
if err != nil {
return err
}
if _, err := tx.Exec("DELETE FROM users"); err != nil {
tx.Rollback()
return err
}
stmt, err := tx.Prepare("INSERT INTO users (id, name) VALUES (?, ?)")
if err != nil {
tx.Rollback()
return err
}
defer stmt.Close()
fixtures := []users{
{
id: 0,
name: "tanaka hime",
},
{
id: 1,
name: "suzuki hina",
},
}
for _, row := range fixtures {
if _, err := stmt.Exec(row.id, row.name); err != nil {
tx.Rollback()
return err
}
}
if err := tx.Commit(); err != nil {
tx.Rollback()
return err
}
return nil
}