【发布时间】:2019-03-11 17:53:59
【问题描述】:
我使用节点 8.11.1 和 pg-promise 8.4.4 来处理 PostgreSQL 中的查询和事务。这是关于节点的,但我想在其他服务器/工具中也是相同的逻辑。
这种情况很常见。我想将图像文件保存在文件夹中,如果成功,则将其详细信息插入数据库,获取返回的 id,然后在辅助的多对多表中进行另一次插入。
显然,我需要一个用于插入查询的事务。但是实际的文件保存呢?我的做法是
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 是否可以在与查询相关的事务中。我什至不知道我在这里的心态是否正确。
请建议或帮我编写代码。
谢谢
【问题讨论】:
-
如果交易失败,删除文件即可。另外,最好使用fs-extra,它包含了promise支持,所以代码是一致的。
-
我在下面添加了详细的答案。如果您对答案感到满意,请接受。
标签: node.js file-upload transactions pg-promise