事务
基本
go
// 1. 开启事务
tx := db.Begin()
if tx.Error != nil {
fmt.Println("开启事务失败")
return
}
// 2. 执行操作1
if err := tx.Create(&User{Name: "李四"}).Error; err != nil {
tx.Rollback() // 失败回滚
fmt.Println("创建用户失败")
return
}
// 3. 执行操作2
if err := tx.Create(&Log{Content: "手动事务测试"}).Error; err != nil {
tx.Rollback()
fmt.Println("创建日志失败")
return
}
// 4. 全部成功 → 提交事务
if err := tx.Commit().Error; err != nil {
fmt.Println("提交失败")
}v1
定义
go
type IUserRepo interface {
WithTx(tx *gorm.DB) IUserRepo
CreateUser(ctx context.Context, user *CreateUserInput) (*UserEntity, error)
}实现
go
type UserRepo struct {
db *gorm.DB
}
func NewUserRepo(db *gorm.DB) userdomain.IUserRepo {
return &UserRepo{
db: db,
}
}
func (r *UserRepo) WithTx(tx *gorm.DB) userdomain.IUserRepo {
return &UserRepo{
db: tx,
}
}
func (r *UserRepo) CreateUser(ctx context.Context, user *userdomain.CreateUserInput) (*userdomain.UserEntity, error) {
model := &userdomain.UserModel{
Account: user.Account,
Email: user.Email,
Phone: user.Phone,
Nickname: user.Nickname,
}
if err := r.db.WithContext(ctx).Create(model).Error; err != nil {
return nil, err
}
return userdomain.Model2entity(model), nil
}使用
go
s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
user := &userdomain.CreateUserInput{
Account: email,
Email: email,
Phone: fmt.Sprintf("unbound:%s", email),
Nickname: nick,
}
userRepo := s.userRepo.WithTx(tx)
userEntity, err := userRepo.CreateUser(ctx, user)
if err != nil {
return err
}
authRepo := s.repo.WithTx(tx)
err = authRepo.CreateAuth(ctx, &authdomian.UserAuthEntity{
ID: userEntity.ID,
Password: string(hash),
})
if err != nil {
return err
}
return nil
})