gorm 中的事务运用

本文介绍了在Go语言中使用Gorm框架进行数据库操作时如何实现事务管理,提供了三种方式:业务层事务、DAO层事务以及利用上下文传递事务。详细展示了如何在函数中开始、提交和回滚事务,确保数据一致性。
摘要由CSDN通过智能技术生成

使用背景

在编写业务代码的过程中,如果涉及到多张表的更新操作,为了确保数据的一致性,我们会在业务代码的过程中加上事务的控制,那么针对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
    评论
GORM和SQLite3都是常用的Go语言数据库操作库和关系数据库引擎。GORM是一个优秀的ORM(Object Relational Mapping)库,提供了对关系数据库的高级抽象和操作,而SQLite3是一种轻量级的嵌入式关系数据库引擎。 在并发环境下使用GORM和SQLite3需要特别注意事项。SQLite3本身支持并发读取,但是不支持并发写入。这是因为SQLite3的设计目标是提供一种适用于嵌入式设备和轻量级应用的简单数据库系统,不适合高并发写入的场景。 在使用GORM时,如果需要在并发环境下进行数据库操作,我们需要注意以下几点: 1. 连接池管理:GORM默认使用连接池管理数据库连接。在并发环境下,需要确保连接池的合理配置,以防止连接的过度竞争和资源不足。 2. 事务管理:GORM提供了事务支持,可以在事务执行多个数据库操作。在并发环境下,我们可以通过使用事务来确保数据的一致性和并发安全。 3. 并发写入冲突:由于SQLite3的限制,在并发写入的场景下可能会遇到写入冲突的问题。这时,我们可以使用GORM的一些特性,如乐观锁或悲观锁等,来解决并发写入的冲突问题。 4. 数据库连接共享:在并发环境下,多个Goroutine可能共享同一个数据库连接。因此,需要保证共享连接的正确使用,以避免竞争条件和数据不一致的问题。 综上所述,GORM和SQLite3在并发环境下需要特别注意连接池管理、事务管理、并发写入冲突和数据库连接共享等问题。合理使用GORM的特性和SQLite3的功能,可以在并发场景下实现数据的一致性和安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值