Home  >  Article  >  Backend Development  >  Gorm transaction error error = transaction committed or rolled back

Gorm transaction error error = transaction committed or rolled back

WBOY
WBOYforward
2024-02-10 23:09:07568browse

Gorm 事务错误 error = 事务已提交或回滚

php editor Youzi will introduce you to a common error message in this article: "Gorm transaction error error = transaction has been committed or rolled back". When using Gorm for database operations, you sometimes encounter this error, which is confusing. This article will explain the cause of this error and possible solutions in detail to help readers solve this problem and perform database operations smoothly.

Question content

My goal is to do transaction management in the code below. If something goes wrong with one of the strategies, I try to roll back. While testing the code, I noticed that if the rollback or commit command is run once, it gives the error = transaction has been committed or rolled back a second time. How to fix this error?

func (d *DistributeService) Distribute(vehicleNumberPlate string, request model.DistributeRequest) (*model.DistributeResponse, error) {
    var response model.DistributeResponse
    response.Vehicle = vehicleNumberPlate
    var routeList []model.RouteResponse
    tx := d.repo.BeginTransaction()
    for _, routes := range request.RouteRequest {
        var routeResponse model.RouteResponse
        strategy, isStrategyExists := d.strategies[routes.DeliveryPoint]
        if isStrategyExists {
            resp, err := strategy.Distribute(routes.Deliveries, vehicleNumberPlate, tx)
            if err != nil {
                tx.Rollback()
                logrus.Errorf("Error while distributing: %v", err)
                return nil, err
            }
            routeResponse.DeliveryPoint = routes.DeliveryPoint
            routeResponse.Deliveries = *resp
            routeList = append(routeList, routeResponse)
        } else {
            logrus.Errorf("Invalid delivery point: %v", routes.DeliveryPoint)
            return nil, errors.New("invalid delivery point")
        }
    }
    response.RouteResponse = routeList
    err := d.checkSackPackagesAreUnloaded()
    tx.Commit()
    if err != nil {
        return nil, err
    }
    return &response, nil
}

Workaround

You may be using the same transaction object in each call. If it is closed once - for whatever reason - you need to create a new transaction object.

Why do I say you probably use the same transaction object you asked about? Because you're basically passing a pointer to d *DistributeService. Then use tx := d.repo.BeginTransaction(). We can't tell what this 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 each time this method is called, e.g. using tx := db.Begin(), as described in the Documentation.

The above is the detailed content of Gorm transaction error error = transaction committed or rolled back. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete