Я использую узел 8.11.1 с pg-promise 8.4.4 для обработки запросов и транзакций в PostgreSQL.Речь идет об узле, но я думаю, такая же логика и в других серверах / инструментах.
Сценарий распространен.Я хочу сохранить файл изображения в папке, а затем, если это успешно, вставить его данные в базу данных, получить возвращенный идентификатор, а затем выполнить еще одну вставку во вторичной таблице «многие ко многим».
Ясно, что мне нужна транзакция для запросов на вставку.Но как насчет фактического сохранения файла?Мой подход -
fs.rename(oldpath, newpath, (err) => {
if (err){throw new Error ;}
db.tx('my-transaction', t => {
return t.one('INSERT INTO images(whatever) VALUES($1) RETURNING id', ['whatever'])
.then(user => {
return t.batch([
t.none('INSERT INTO mtm(userId, name) VALUES($1, $2)', [user.id, 'created'])
]);
});
})
.then(data => {
// success
})
.catch(error => {
// error
});
}); //fs rename
Хорошо, если при сохранении файла изображения с помощью fs.rename
ошибки нет, продолжите транзакцию.
Если при сохранении изображения произошла ошибка, ничего не будет выполнено, так что все хорошо.
Но проблема в , что если изображение сохранено и в транзакции произошла ошибка?Я закончу с сохраненным изображением и ничего в базе данных.Конечно, пользователь получит ошибку и будет вынужден повторно загрузить его, но У меня все еще есть изображения на моем сервере, которые не связаны ни с чем. Я бы хотел этого избежать.
Решением было бы включить сохранение изображения в транзакцию, поэтому, если что-то не получится, ничего не будет завершено.Как я могу это сделать?Я не знаю, может ли файловый API быть внутри транзакции, связанной с запросом.Я даже не знаю, правильно ли я здесь настроен.
Пожалуйста, дайте мне совет или помогите мне написать код.
Спасибо