GORM の トランザクションブロックの書き方
最近 Golang の ORM の GORM のトランザクションブロックについて勉強した。トランザクションブロックはまだリリースされて間もなくサンプル例などもあまりないので使用方法を書いておく。
本家 GORM のサイト: http://gorm.io/ja_JP/docs/transactions.html
↑ のサイトにも使い方は書いてあるが、関数化してトランザクションの値を return しているので1つの関数内でエラーハンドリングまで行う方法について書く。
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
)
type Example1 struct {
Message: string
}
type Example2 struct {
Message: string
}
func TransactionExample(db *gorm.DB) error {
fmt.Println("トランザクションを開始します")
err := db.Transaction(func(tx *gorm.DB) error {
// データベース操作をトランザクション内で行う
if err := tx.Create(Example1{Message: "トランザクション例"}).Error; err != nil {
// エラーを返した場合はロールバックされる
return err
}
// Example1と同じトランザクション内で行いたい処理
if err := tx.Create(Example2{Message: "Example1と同じトランザクション内で行いたい処理"}).Error; err != nil {
// エラーを返した場合はロールバックされる
return err
}
// nil を返すとコミットされる
return nil
})
if err != nil {
fmt.Println("トランザクション内でエラーが発生しました")
return err
}
fmt.Println("トランザクションが正常に終了しました")
return nil
}
func main() {
db, err := gorm.Open("postgres", "host=myhost port=myport user=gorm dbname=gorm password=mypassword")
defer db.Close()
if err := TransactionExample(db); err != nil {
fmt.Printf("%v", err)
}
}