Skip to content

Instantly share code, notes, and snippets.

@vurihuang
Last active July 18, 2019 03:04
Show Gist options
  • Save vurihuang/3470d3de77cbeafa631a7bdd06c04ac1 to your computer and use it in GitHub Desktop.
Save vurihuang/3470d3de77cbeafa631a7bdd06c04ac1 to your computer and use it in GitHub Desktop.
go orm with transaction.
package main
import (
"errors"
"fmt"
"sync"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
)
var db *gorm.DB
// Transaction .
type Transaction struct {
once sync.Once
rollback bool
DB *gorm.DB
}
// NewTransaction .
func NewTransaction(db *gorm.DB) (*gorm.DB, *Transaction) {
tx := &Transaction{DB: db}
return db, tx
}
// Close .
func (t *Transaction) Close() {
t.once.Do(func() {
if t.rollback {
t.DB.Rollback()
} else {
t.DB.Commit()
}
})
}
// Fail .
func (t *Transaction) Fail() {
t.rollback = true
}
// User .
type User struct {
ID int `gorm:"primary_key"`
Username string
Password string
}
func init() {
db, _ = gorm.Open("mysql", "root:@tcp(localhost:3306)/test?charset=utf8mb4&parseTime=true&loc=Local")
db.SingularTable(true)
db.LogMode(true)
}
// CreateUser .
func CreateUser(db *gorm.DB, user User) error {
_, tx := NewTransaction(db.Begin())
defer tx.Close()
err := tx.DB.Create(&user).Error
return err
}
// CreateUserWithConn .
func CreateUserWithConn(db *gorm.DB, user User) error {
conn, tx := NewTransaction(db.Begin())
defer tx.Close()
var u User
conn.Model(User{}).Where("username = ?", user.Username).First(&u)
fmt.Println("found user without transaction conn: ", u)
tx.Fail()
return errors.New("create user faild")
}
func main() {
user := User{Username: "foo", Password: "bar"}
_ = CreateUser(db, user)
err := CreateUserWithConn(db, user)
if err != nil {
fmt.Println("create user failed, db rollback.")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment