普通事务

使用 Transaction() 可以开启事务,在其中传入一个签名为 func(tx *gorm.DB) error 的函数,在函数内操作,如果返回的 error 不为空,则这些操作都作废

1
2
3
4
5
6
7
GLOBAL_DB.Transaction(
func(tx *gorm.DB) error {
// 在这里做些事情
// tx.Create(...)

return nil
})

事务可以嵌套,如果内部事务出错,只会回滚内部语句


手动事务

另外一种形式是手动事务

1
2
3
4
5
6
7
tx := GLOBAL_DB.Begin() // 开启事务
// 在这里做些事情
// tx.Create(...)
tx.Rollback() // 回滚事务(直接回到初始点,上面的都作废)
// 在这里做些事情
// tx.Create(...)
tx.Commit() // 提交事务

进阶一点的操作是设置存档点,还有手动回档

1
2
3
4
5
6
7
tx := GLOBAL_DB.Begin() // 开启事务
// ...
tx.SavePoint("savepoint1") // 创建保存点
// ...
tx.RollbackTo("savepoint1") // 回滚到保存点
// ...
tx.Commit() // 提交事务

GORM 的事务在多协程场景下貌似手动上锁,请见gorm的坑