gorm 中的事务运用

使用背景

在编写业务代码的过程中,如果涉及到多张表的更新操作,为了确保数据的一致性,我们会在业务代码的过程中加上事务的控制,那么针对go 语言中,如果我们使用gorm框架改如何操作呢?

gorm中使用事务的几种方式

  • 方式一(业务层事务)
func NewTransaction() *gorm.DB {
	return suit.GetGormClient().Begin()
}

tx := s.AlarmDao.NewTransaction()
defer tx.Rollback()

...(具体业务处理)

err = tx.Commit().Error
  • 方式二(dao层事务)
func (r *Repo) TxUpdateBonus(ctx context.Context, bonus *entity.Bonus, transaction *entity.Transaction) error {
	return r.Connection().Transaction(func(tx *gorm.DB) error {
		if bonus.ID < 1 {
			if err := tx.WithContext(ctx).Create(bonus).Error; err != nil {
				return err
			}
		} else {
			if err := tx.WithContext(ctx).Model(bonus).Updates(bonus.Conv2Map()).Error; err != nil {
				return err
			}
		}

		if err := tx.WithContext(ctx).Create(transaction).Error; err != nil {
			return err
		}
		return nil
	})
}
  • 方式三(业务层)
var dbClient *DbClient

type DbClient struct {
	MysqlClient *gorm.DB
}

func NewDbClient() *DbClient {
	dbClient = &DbClient{}
	dbClient.MysqlClient = suit.GetGormClient()
	return dbClient
}

type contextTxKey struct{}

type TxFn func(context.Context) error

func ExecTx(ctx context.Context, fn TxFn) error {
	return suit.GetGormClient().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		ctx = context.WithValue(ctx, contextTxKey{}, tx)
		return fn(ctx)
	})
}

func GetTxGorm(ctx context.Context) (db *gorm.DB, ok bool) {
	db, ok = ctx.Value(contextTxKey{}).(*gorm.DB)
	return
}


err = dao.ExecTx(ctx, func(ctx context.Context) error {
	instance.DeletedAt = time.Now()
	instance.UpdatedAt = time.Now()
	instance.State = constant.InstanceStateDeleteSuccess
	err = a.MongodbInstance.UpdateOrInsert(ctx, &instance)
	if err != nil {
		return err
	}
	req := &middleware.DeleteMongoDBDBInstanceRequest{}
	err = a.MiddlewareClient.DeleteMongoDBDBInstance(ctx, common, req)
	if err != nil {
		return err
	}
	err = a.deleteAndRefundResource(ctx, &instance, true, false)
	return err
})


func (a *MongodbInstance) dbClient(ctx context.Context) *gorm.DB {
	if tx, ok := dao.GetTxGorm(ctx); ok {
		return tx
	}
	return a.DB.MysqlClient
}

func (a *MongodbInstance) UpdateOrInsert(ctx context.Context, p *po.MongodbInstance) (err error) {
	client := a.dbClient(ctx)
	if p.Id == 0 {
		err = client.Table(po.MongodbInstance{}.TableName()).Create(p).Error
		return
	}
	err = client.Table(po.MongodbInstance{}.TableName()).Select("*").Omit("created_at").Updates(p).Error
	return
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值