Gorm事务错误:错误=事务已经提交或回滚。

huangapple go评论164阅读模式
英文:

Gorm Transaction Error error = transaction has already been committed or rolled back

问题

我正在尝试在下面的代码中进行事务管理。如果其中一个策略出现错误,我尝试进行回滚操作。在测试代码时,我注意到如果回滚或提交命令成功执行一次,第二次执行时会出现错误,提示"事务已经被提交或回滚"。我该如何解决这个错误?

  1. func (d *DistributeService) Distribute(vehicleNumberPlate string, request model.DistributeRequest) (*model.DistributeResponse, error) {
  2. var response model.DistributeResponse
  3. response.Vehicle = vehicleNumberPlate
  4. var routeList []model.RouteResponse
  5. tx := d.repo.BeginTransaction()
  6. for _, routes := range request.RouteRequest {
  7. var routeResponse model.RouteResponse
  8. strategy, isStrategyExists := d.strategies[routes.DeliveryPoint]
  9. if isStrategyExists {
  10. resp, err := strategy.Distribute(routes.Deliveries, vehicleNumberPlate, tx)
  11. if err != nil {
  12. tx.Rollback()
  13. logrus.Errorf("Error while distributing: %v", err)
  14. return nil, err
  15. }
  16. routeResponse.DeliveryPoint = routes.DeliveryPoint
  17. routeResponse.Deliveries = *resp
  18. routeList = append(routeList, routeResponse)
  19. } else {
  20. logrus.Errorf("Invalid delivery point: %v", routes.DeliveryPoint)
  21. return nil, errors.New("invalid delivery point")
  22. }
  23. }
  24. response.RouteResponse = routeList
  25. err := d.checkSackPackagesAreUnloaded()
  26. tx.Commit()
  27. if err != nil {
  28. return nil, err
  29. }
  30. return &response, nil
  31. }

以上是你要翻译的内容。

英文:

I'm aiming to do transaction management in the code below. If there is an error in one of the strategies, I am trying to rollback. While testing the code, I noticed that if the rollback or commit command works once, it gives error = transaction has already been committed or rolled back the second time. How can I resolve this error?

  1. func (d *DistributeService) Distribute(vehicleNumberPlate string, request model.DistributeRequest) (*model.DistributeResponse, error) {
  2. var response model.DistributeResponse
  3. response.Vehicle = vehicleNumberPlate
  4. var routeList []model.RouteResponse
  5. tx := d.repo.BeginTransaction()
  6. for _, routes := range request.RouteRequest {
  7. var routeResponse model.RouteResponse
  8. strategy, isStrategyExists := d.strategies[routes.DeliveryPoint]
  9. if isStrategyExists {
  10. resp, err := strategy.Distribute(routes.Deliveries, vehicleNumberPlate, tx)
  11. if err != nil {
  12. tx.Rollback()
  13. logrus.Errorf("Error while distributing: %v", err)
  14. return nil, err
  15. }
  16. routeResponse.DeliveryPoint = routes.DeliveryPoint
  17. routeResponse.Deliveries = *resp
  18. routeList = append(routeList, routeResponse)
  19. } else {
  20. logrus.Errorf("Invalid delivery point: %v", routes.DeliveryPoint)
  21. return nil, errors.New("invalid delivery point")
  22. }
  23. }
  24. response.RouteResponse = routeList
  25. err := d.checkSackPackagesAreUnloaded()
  26. tx.Commit()
  27. if err != nil {
  28. return nil, err
  29. }
  30. return &response, nil
  31. }

答案1

得分: 1

你可能在每次调用中使用相同的事务对象。
如果它被关闭了一次 - 不管出于什么原因 - 你需要创建一个新的事务对象。

你为什么会问我说你可能在使用相同的事务对象呢?
因为你基本上是在传递一个指向 d *DistributeService 的指针。
然后使用 tx := d.repo.BeginTransaction()。我们无法确定这段代码的具体作用,但我很确定你在这里返回的是相同的事务对象,用于后续的运行。

解决方法是在每次调用该方法时创建一个新的事务对象,例如使用 tx := db.Begin(),如文档所述。

英文:

You're probably using the same transaction object in each call.
If it was closed once - for whatever reason - you need to create a new transaction object.

Why do I say you are probably using the same transaction object you ask?
Because you're basically passing a pointer to d *DistributeService.
And then use tx := d.repo.BeginTransaction(). We can't tell what that code does, but I'm pretty sure you're returning the same transaction object here for subsequent runs.

The solution is to create a new transaction object every time this method is called, f.e. with tx := db.Begin() as described in the docs.

huangapple
  • 本文由 发表于 2023年5月13日 18:54:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76242351.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定