Go 语言中实现事务和 SQL 原生语句其实是非常接近的。调用 db.Begin()
得到 *sql.Tx
对象,使用 tx.Exec()
执行一系列操作,如果发生错误,通过 tx.Rollback()
回滚,如果没有发生错误,则通过 tx.Commit()
提交。
type TxFunc func(*session.Session) (interface{}, error)
func (engine *Engine) Transaction(f TxFunc) (result interface{}, err error) {
s := engine.NewSession()
if err := s.Begin(); err != nil {
return nil, err
}
defer func() {
if p := recover(); p != nil {
_ = s.Rollback()
panic(p) // re-throw panic after Rollback
} else if err != nil {
_ = s.Rollback() // err is non-nil; don't change it
} else {
err = s.Commit() // err is nil; if Commit returns error update err
}
}()
return f(s)
}