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.
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 }
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!