Skip to content

Instantly share code, notes, and snippets.

@j2gg0s
Created August 26, 2020 03:47
Show Gist options
  • Select an option

  • Save j2gg0s/689beabb2a2c9056a41546039cfba36a to your computer and use it in GitHub Desktop.

Select an option

Save j2gg0s/689beabb2a2c9056a41546039cfba36a to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
"sync"
)
type User struct {
ID string `gorm:"primary_key"`
Name string
Status int
}
func (User) TableName() string {
return "user"
}
var gormDB *gorm.DB
func init() {
var err error
gormDB, err = gorm.Open(
"postgres",
"postgres://postgres:rcrai@localhost:5432/example?sslmode=disable")
if err != nil {
panic(err)
}
}
func ExampleUpdateInTransaction() {
var t1, t2 sync.WaitGroup
var start sync.WaitGroup
var end sync.WaitGroup
start.Add(1)
t1.Add(1)
t2.Add(1)
gormDB.Model(&User{}).Where("name=?", "j2gg0s").Update("status", 1)
if gormDB.Error != nil {
panic(gormDB.Error)
}
end.Add(1)
go func() {
gormDB.Transaction(func(tx *gorm.DB) error {
defer end.Done()
start.Done()
t1.Wait()
defer t2.Done()
// t2 select and update
user := new(User)
tx.Where("name=?", "j2gg0s").First(user)
if tx.Error != nil {
return tx.Error
}
oldStatus := user.Status
tx.Model(user).
Where("id=?", user.ID).
Update("status", user.Status+1)
if tx.Error != nil {
fmt.Println(tx.Error)
}
fmt.Printf("Update j2gg0s.Status from %d to %d in transaction A\n", oldStatus, user.Status)
return tx.Error
})
}()
end.Add(1)
gormDB.Transaction(func(tx *gorm.DB) error {
defer end.Done()
start.Wait()
// t1 select
user := &User{}
tx.Where("name=?", "j2gg0s").First(user)
if tx.Error != nil {
return tx.Error
}
oldStatus := user.Status
t1.Done()
t2.Wait()
// t3 update 但是数据已经被其他人更新了
tx.Model(user).
Where("id=?", user.ID).
Update("status", user.Status+10)
fmt.Printf("Update j2gg0s.Status from %d to %d in transaction B\n", oldStatus, user.Status)
return tx.Error
})
end.Wait()
user := &User{}
gormDB.Where("name=?", "j2gg0s").First(user)
if gormDB.Error != nil {
panic(gormDB.Error)
}
fmt.Printf("Current j2gg0s.Status is %d\n", user.Status)
// output: Update j2gg0s.Status from 1 to 2 in transaction A
// Update j2gg0s.Status from 1 to 11 in transaction B
// Current j2gg0s.Status is 11
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment