php小编柚子在这篇文章中将为大家介绍一个常见的错误信息:“Gorm 事务错误 error = 事务已提交或回滚”。在使用Gorm进行数据库操作时,有时候会遇到这个错误,让人困惑不解。本文将详细解释这个错误的原因以及可能的解决方案,帮助读者解决这个问题,顺利进行数据库操作。
问题内容
我的目标是在下面的代码中进行事务管理。如果其中一项策略出现错误,我会尝试回滚。在测试代码时,我注意到如果回滚或提交命令运行一次,它会给出错误=事务已被提交或回滚第二次。如何解决此错误?
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
}
解决方法
您可能在每次调用中使用相同的事务对象。 如果它被关闭一次 - 无论出于何种原因 - 您需要创建一个新的事务对象。
为什么我说您可能使用您询问的相同事务对象?
因为您基本上将指针传递给 d *DistributeService
。
然后使用 tx := d.repo.BeginTransaction()
。我们无法判断该代码的作用,但我很确定您将在此处返回相同的事务对象以供后续运行。
解决方案是每次调用此方法时创建一个新的事务对象,例如使用 tx := db.Begin()
,如 文档 中所述。
以上就是Gorm 事务错误 error = 事务已提交或回滚的详细内容,更多请关注编程网其它相关文章!