教程

事务

qianmoQqianmoQ· 更新于 2026-09-23· 阅读 6 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

禁用默认事务

GORM 在执行写入(创建/更新/删除)操作时会运行在事务中以确保数据一致性。如果不需要,你可以在初始化时禁用它,禁用后性能将提升约 30% 以上。


db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
  SkipDefaultTransaction: true,
})


tx := db.Session(&Session{SkipDefaultTransaction: true})
tx.First(&user, 1)
tx.Find(&users)
tx.Model(&user).Update("Age", 18)

事务

要在事务中执行一组操作,一般的流程如下。

泛型 API

ctx := context.Background()


err := db.Transaction(func(tx *gorm.DB) error {
  
  if err := gorm.G[Animal](tx).Create(ctx, &Animal{Name: "Giraffe"}); err != nil {
    
    return err
  }

  if err := gorm.G[Animal](tx).Create(ctx, &Animal{Name: "Lion"}); err != nil {
    return err
  }

  
  return nil
})

传统 API

db.Transaction(func(tx *gorm.DB) error {
  
  if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
    
    return err
  }

  if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
    return err
  }

  
  return nil
})

嵌套事务

GORM 支持嵌套事务,你可以在更大的事务范围内回滚部分操作,例如:

db.Transaction(func(tx *gorm.DB) error {
  tx.Create(&user1)

  tx.Transaction(func(tx2 *gorm.DB) error {
    tx2.Create(&user2)
    return errors.New("rollback user2") 
  })

  tx.Transaction(func(tx3 *gorm.DB) error {
    tx3.Create(&user3)
    return nil
  })

  return nil
})

手动控制事务

Gorm 支持直接调用事务控制函数(commit / rollback),例如:


tx := db.Begin()


tx.Create(...)




tx.Rollback()


tx.Commit()

具体示例

func CreateAnimals(db *gorm.DB) error {
  
  tx := db.Begin()
  defer func() {
    if r := recover(); r != nil {
      tx.Rollback()
    }
  }()

  if err := tx.Error; err != nil {
    return err
  }

  if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
     tx.Rollback()
     return err
  }

  if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
     tx.Rollback()
     return err
  }

  return tx.Commit().Error
}

SavePoint、RollbackTo

GORM 提供了 SavePoint、RollbackTo 用于保存保存点和回滚到保存点,例如:

tx := db.Begin()
tx.Create(&user1)

tx.SavePoint("sp1")
tx.Create(&user2)
tx.RollbackTo("sp1") 

tx.Commit() 

GitHub tag (latest SemVer)

评论

登录后参与评论

正在加载评论…