【问题标题】:Combine file API with transactions for file saving or deleting将文件 API 与用于文件保存或删除的事务相结合
【发布时间】: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


【解决方案1】:

如果交易失败,只需删除文件(或者如果您愿意,您可以将其重命名):

const fs = require('fs-extra');

async function saveAll(oldpath, newpath) {
    await fs.rename(oldpath, newpath);
    try {
        return await db.tx('my-transaction', async t => {
            const imageId = await t.one('INSERT INTO images(whatever) VALUES($1) RETURNING id', ['whatever'], a => a.id);
            await t.none('INSERT INTO mtm(userId, name) VALUES($1, $2)', [imageId, 'created']);
            return imageId;
        });
    } catch (e) {
        await fs.unlink(newpath); // deleting the file
        throw e;
    }
}

如果成功,函数saveAll 将返回新的imageId,如果失败则抛出错误:

async test() {
    try {
        const imageId = await saveAll('old-path', 'new-path');
        // we are all good
    } catch(e) {
        // something failed, as per the error details
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-24
    • 2016-11-20
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多