Maison > Article > développement back-end > Erreur d'erreur de transaction Gorm = transaction validée ou annulée
l'éditeur php Youzi vous présentera un message d'erreur courant dans cet article : "Erreur de transaction Gorm = transaction a été validée ou annulée". Lorsque vous utilisez Gorm pour des opérations de base de données, vous rencontrez parfois cette erreur, qui prête à confusion. Cet article expliquera en détail la cause de cette erreur et les solutions possibles pour aider les lecteurs à résoudre ce problème et à effectuer les opérations de base de données en douceur.
Mon objectif est de faire la gestion des transactions dans le code ci-dessous. Si quelque chose ne va pas avec l’une des stratégies, j’essaie de revenir en arrière. En testant le code, j'ai remarqué que si la commande rollback ou commit est exécutée une fois, elle donne l'erreur = la transaction a été validée ou annulée une seconde fois. Comment corriger cette erreur ?
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 }
Vous utilisez peut-être le même objet de transaction à chaque appel. S'il est fermé une fois - pour une raison quelconque - vous devez créer un nouvel objet de transaction.
Pourquoi ai-je dit que vous utilisiez probablement le même objet de transaction que celui que vous avez demandé ?
Parce que vous passez essentiellement un pointeur vers d *DistributeService
.
Alors utilisez tx := d.repo.BeginTransaction()
. Nous ne pouvons pas dire ce que fait ce code, mais je suis presque sûr que vous renvoyez ici le même objet de transaction pour les exécutions ultérieures.
La solution est de créer un nouvel objet de transaction à chaque fois que cette méthode est appelée, par exemple en utilisant tx := db.Begin()
comme décrit dans la documentation.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!