Skip to content

Commit

Permalink
实现乐观锁
Browse files Browse the repository at this point in the history
  • Loading branch information
Kotodian committed Aug 16, 2021
1 parent 3809b0e commit 47868c2
Showing 1 changed file with 34 additions and 0 deletions.
34 changes: 34 additions & 0 deletions datasource/orm/orm.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import (
var (
db *gorm.DB
)
var (
ErrRetryMax = errors.New("maximum number of retries exceeded")
)

func GetDB() *gorm.DB {
return db
Expand Down Expand Up @@ -40,6 +43,9 @@ type Object interface {
UpdatedAt() int64
// 删除时间
DeletedAt() int64
GetVersion() int
SetVersion(version int)

// 钩子函数
AfterCreate(db *gorm.DB) error
AfterUpdate(db *gorm.DB) error
Expand Down Expand Up @@ -75,3 +81,31 @@ func Delete(obj Object, deleteFunc ...DeleteFunc) error {
func UpdateColumn(obj Object, f map[string]interface{}) error {
return db.Model(obj).Updates(f).Error
}

func UpdateWithOptimistic(db *gorm.DB, obj Object, f map[string]interface{}) error {
if f == nil {
return nil
}
return updateWithOptimistic(db, obj, f, 3, 0)
}

func updateWithOptimistic(db *gorm.DB, obj Object, f map[string]interface{}, retryCount, currentRetryCount int) error {
if currentRetryCount > retryCount {
return ErrRetryMax
}
currentVersion := obj.GetVersion()
obj.SetVersion(currentVersion + 1)
f["version"] = currentVersion + 1
column := db.Model(obj).Where("version", currentVersion).Updates(f)
affected := column.RowsAffected
if affected == 0 {
time.Sleep(100 * time.Millisecond)
db.First(obj)
currentRetryCount++
err := updateWithOptimistic(db, obj, f, retryCount, currentRetryCount)
if err != nil {
return err
}
}
return column.Error
}

0 comments on commit 47868c2

Please sign in to comment.