• Как лучше реализовать транзакцию?

    yellow79
    @yellow79
    Senior Software Engineer
    В целом всё выглядит не плохо, но будет лучше, если контекст будем принимать на вход. Так же было не плохо отменять транзакцию в случае ошибки, ну и закрывать prepare тоже не помешает. На каждую итерацию цикла вовсе не обязательно содавать свой собственный prepare, достаточно одного

    func (db *Requests) StorePhotos(ctx context.Context, photos []Photo) error {
    	ctx, cancel := context.WithTimeout(ctx, time.Minute*2)
    	defer cancel()
    
    	tx, err := db.BeginTx(ctx, nil)
    	if err != nil {
    		return err
    	}
    	defer tx.Rollback()
    
    	stmnt, err := tx.PrepareContext(ctx, "INSERT INTO photos (id, owner_id, req_id, url) VALUES ($1, $2, $3, $4)")
    	if err != nil {
    		return err
    	}
    	defer stmnt.Close()
    
    	for _, photo := range photos {
    		if _, err = stmnt.ExecContext(ctx, photo.ID, photo.OwnerID, photo.ReqID, photo.URL); err != nil {
    			return err
    		}
    	}
    
    	return tx.Commit()
    }
    Ответ написан
    5 комментариев