Gin实战7:事务管理升级!Biz层接管事务控制


一、引言

上一次我们已经实现了通过Gorm Gen实现数据库基础操作,在之前的代码结构中,Data 层负责实现数据操作,而Biz层则专注于业务逻辑处理。 但实际开发中经常会需要开启事务处理多个表的操作,此时需要考虑事务控制方案。如果事务控制在Data层实现,许多业务层的逻辑就不得不放到Data层,Data层将会变得非常臃肿。 因此我们需要考虑将事务控制移到Biz层,以实现更清晰、更易维护的代码结构。

二、将事务控制移到Biz层

  1. Biz层事务控制的好处

    • 可以清晰地分离数据操作和事务控制,提高代码可维护性
    • 数据层无感知开启事务,专注于数据处理。
    • 数据层的事务控制逻辑可以复用,减少重复代码。
  2. 如何实现? 事务处理的核心思想是:在业务逻辑中,通过上下文传递事务对象,并在需要时开启事务,并在业务逻辑执行完成后提交或回滚事务。 我们同样借鉴kratos/example 中的[transaction] 部分的实现方案。

三、实战改造步骤

  1. Biz层实现
    • 新增 Transaction 接口 定义
type Transaction interface {
	QueryTx(context.Context, func(ctx context.Context) error) error
}
  1. Data层实现 Transaction
    • 事务上下文传递方案(context传递事务对象)
type contextQueryTxKey struct{}
type Data struct {
	db *gorm.DB
}

func (d *Data) DB(ctx context.Context) *query.Query {
	tx, ok := ctx.Value(contextQueryTxKey{}).(*query.Query)
	if ok {
		return tx
	}
	return query.Use(d.db)
}
func (d *Data) QueryTx(ctx context.Context, fn func(ctx context.Context) error) error {
	q := query.Use(d.db)
	return q.Transaction(func(tx *query.Query) error {
		ctx = context.WithValue(ctx, contextQueryTxKey{}, tx)
		return fn(ctx)
	})
}
  1. Biz层使用事务
a.tx.QueryTx(ctx, func(ctx context.Context) error {
		// todo 
})

需要注意的是data 层需要用 DB(ctx) 方法获取Query对象

总结

  • 通过将事务控制移到Biz层,实现了更清晰、更易维护的代码结构。
  • 通过上下文传递事务对象,在需要时开启事务,并在业务逻辑执行完成后提交或回滚事务,实现了事务控制的核心思想。

感谢你的关注和支持,回复【Gin实战】 获取完整代码

wx

关注公众号

©2017-2023 鲁ICP备17023316号-1 Powered by Hugo