Gormでトランザクションを利用する時の覚書。
DBとの接続およびトランザクションの開始
以下ではTranscation関数を定義し、その中でCRUDの処理を実行するようにしている。
そして、deferでは最終的にTransaction関数から返ってきたerrがnilかどうかを見てロールバックするかコミットするかを判断している。
main.go
func main() {
DBMS := "mysql"
USER := "root"
PASS := "mysql"
PROTOCOL := "tcp(localhost:3306)"
DBNAME := "sampleDB"
CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME
db, err := gorm.Open(DBMS, CONNECT)
if err != nil {
panic(err.Error())
}
tx := db.Begin()
// Transaction関数が存在し、その引数にはトランザクションの情報とCreate処理を盛り込んだ関数を渡す
err := Transaction(tx, createFunc)
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}
}
Transaction関数の中身とその引数となるcreateFunc関数
main.go
type CreateFunc func(tx *gorm.DB) error
func Transaction(
tx *gorm.DB,
createFunc CreateFunc,
) error {
// create処理を行う
err := createFunc(tx)
// create処理が失敗したらRollbackさせるためにerrを返す
return err
}
// createFuncではなんらかのCreate処理を行う
func createFunc(tx *gorm.DB) error {
creature := Creature{Name: "Human", Type: "Mammal"}
tx.NewRecord(creature)
return tx.Create(&creature).Error // 適宜必要な戻り値があればそれも盛り込んで返すようにする
}
Createに加えてupdateやdeleteなどの他の処理も行いたい場合はcreateFuncのように処理を書いて、Transaction関数内に追加していく。