@someoneyoudunno

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

Есть таблица, куда надо сохранять информацию о фотографиях. Написал такой код, можете посмотреть? Или лучше сохранять по одной фотографии, но мне кажется это слишком затратно и лучше на транзакциях.
func (db *Requests) StorePhotos(photos []Photo) error {
	tx, err := db.Begin()

	if err != nil {
		return err
	}
	for _, photo := range photos {
		ctx, cancel := context.WithTimeout(context.Background(), time.Minute*2)
		stmnt, err := tx.PrepareContext(ctx, "INSERT INTO photos (id, owner_id, req_id, url) VALUES ($1, $2, $3, $4)")

		if err != nil {
			cancel()
			return err
		}

		_, err = stmnt.Exec(photo.ID, photo.OwnerID, photo.ReqID, photo.URL)

		if err != nil {
			cancel()
			return err
		}

		cancel()
	}
	tx.Commit()

}
  • Вопрос задан
  • 177 просмотров
Решения вопроса 1
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()
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@rPman
insert into table (x,y,z) values (?,?,?), (?,?,?), (?,?,?), ...


а значения передавай как обычно сразу все, массивом, в правильном порядке
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы