go-mongox icon indicating copy to clipboard operation
go-mongox copied to clipboard

添加事务支持

Open codepzj opened this issue 9 months ago • 3 comments

使用场景 | Use Case Scenario

请尽可能详细地描述您希望添加的功能。包括其具体用途和实现的效果。| Please describe the feature you would like to be added in as much detail as possible. Include its specific use case and how it would function.

为mongox提供事务支持

可行方案 | Feasible Solutions

如果你知道有框架提供了类似功能,可以在这里描述,并且给出文档或者例子。 | If you are aware of any frameworks that provide similar features, please describe them here and include documentation or examples.

通过mongo的官方文档封装mongox的事务方法,延用类似gorm开启事务的一套方法。

如果你有设计思路或者解决方案,请在这里提供。你可以提供多个方案,并且给出自己的选择。| If you have any design ideas or proposed solutions, please share them here. You may provide multiple options and explain your preference.

gorm开启自动事务

db.Transaction(func(tx *gorm.DB) error {
  // 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
  if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
    // 返回任何错误都会回滚事务
    return err
  }

  // 返回 nil 提交事务
  return nil
})

mongox期望实现的功能:自动事务

coll通过接口,实现transaction方法,new一个transaction实例,transaction接口实现Auto方法去执行自动事务,传入一个ctx对象,和执行crud的业务逻辑函数 定义Transaction对象

type Transaction struct {
	collection *mongo.Collection
	session    *mongo.Session
}
type ITransaction interface {
	Auto(ctx context.Context, fn func(ctx context.Context) (interface{}, error)) (interface{}, error)
	Begin(ctx context.Context) (*Tx, error)
}
func (t *Transaction) Auto(ctx context.Context, fn func(ctx context.Context) (interface{}, error)) (interface{}, error) {
	// 返回任何错误都会回滚
	defer t.session.EndSession(ctx)
	if err := t.session.StartTransaction(); err != nil {
		return nil, err
	}
	var result interface{}
	err := mongo.WithSession(ctx, t.session, func(sc context.Context) error {
		r, err := fn(sc)
		if err != nil {
			t.session.AbortTransaction(ctx)
			return err
		}
		result = r
		return t.session.CommitTransaction(ctx)
	})

	if err != nil {
		t.session.AbortTransaction(ctx)
		return nil, err
	}

	return result, nil
}

gorm开启手动事务

// 开始事务
tx := db.Begin()

// 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
tx.Create(...)

// ...

// 遇到错误时回滚事务
tx.Rollback()

// 否则,提交事务
tx.Commit()

mongox期望实现的功能:手动事务

type Tx struct {
	SessionCtx context.Context
	session    *mongo.Session
}

gorm手动事务是返回一个游标对象,mongox也应该返回一个携带上下文的游标对象来控制事务

type ITx interface {
	RollBack() error
	Commit() error
}

该结构体实现接口,以便回滚和提交。

其它 | Others

任何你觉得有利于解决问题的补充说明 | Any additional information you think may be helpful in solving the problem.

貌似mongox里面还有callback包,感觉可以在事务中使用callback,还没看。然后自动事务返回的result为一个空接口,感觉可以用反射推断出是单纯的指针类型还是切片指针类型,而且泛型也可使用,但不知道如何才能更好的在事务中实现

codepzj avatar Feb 27 '25 16:02 codepzj

can i take up this task ?

Certainly! However, it would be great if you could explore alternative designs. The current approach outlined in this issue seems to have several areas for improvement. I’m planning to dive into a detailed discussion about it in the coming days.

chenmingyong0423 avatar Mar 13 '25 18:03 chenmingyong0423