当前位置: 首页 > 面试题库 >

使用NodeJS和Postgres的事务链中的可选INSERT语句

廖弘伟
2023-03-14
问题内容

我正在使用 NodeJS / Postgres 构建一个简单的Web应用程序,需要在数据库中进行3次插入。

为了控制语句链,我使用 pg-transaction

我的问题是我必须总是先运行第2个插件,但是我有条件要运行第3个插件。

也许可以以更好的方式构建我的代码(欢迎提出建议)。

这是一个伪代码:

function(req, res) {

  var tx = new Transaction(client);

  tx.on('error', die);

  tx.begin();



  tx.query('INSERT_1 VALUES(...) RETURNING id', paramValues, function(err, result) {

    if (err) {

      tx.rollback();

      res.send("Something was wrong!");

      return;

    }



    var paramValues2 = result.rows[0].id;

    tx.query('INSERT_2 VALUES(...)', paramValues2, function(err2, result2) {

      if (err) {

        tx.rollback();

        res.send("Something was wrong!");

        return;

      }



      // HERE'S THE PROBLEM (I don't want to always run this last statement)

      // If I don't run it, I will miss tx.commit()

      if (req.body.value != null) {

        tx.query('INSERT_3 VALUES(...)', paramValues3, function(err3, result3) {

          if (err) {

            tx.rollback();

            res.send("Something was wrong!");

            return;

          }



          tx.commit();

          res.send("Everything fine!");

        });

      }

    });

  });

}

在每个查询之后, 如果 重复三遍 if(err){} 看起来很丑。

尝试检查一些选项时,我发现了 Sequelize ,但是找不到解决此问题的方法。

欢迎任何建议!

谢谢!


问题答案:

手动交易管理是一条危险的道路,请设法避免这种情况!;)

这是在pg-promise的帮助下正确执行操作的html" target="_blank">方法:

function(req, res) {
    db.tx(t => { // automatic BEGIN
            return t.one('INSERT_1 VALUES(...) RETURNING id', paramValues)
                .then(data => {
                    var q = t.none('INSERT_2 VALUES(...)', data.id);
                    if (req.body.value != null) {
                        return q.then(()=> t.none('INSERT_3 VALUES(...)', data.id));
                    }
                    return q;
                });
        })
        .then(data => {
            res.send("Everything's fine!"); // automatic COMMIT was executed
        })
        .catch(error => {
            res.send("Something is wrong!"); // automatic ROLLBACK was executed
        });
}

或者,如果您更喜欢ES7语法:

function (req, res) {
    db.tx(async t => { // automatic BEGIN
            let data = await t.one('INSERT_1 VALUES(...) RETURNING id', paramValues);
            let q = await t.none('INSERT_2 VALUES(...)', data.id);
            if (req.body.value != null) {
                return await t.none('INSERT_3 VALUES(...)', data.id);
            }
            return q;
        })
        .then(data => {
            res.send("Everything's fine!"); // automatic COMMIT was executed
        })
        .catch(error => {
            res.send("Something is wrong!"); // automatic ROLLBACK was executed
        });
}

更新

在示例中,用ES7 async/ 替换了ES6生成器await,因为pg-promise停止了从9.0.0版本开始支持ES6生成器



 类似资料:
  • 已经有一段时间没有使用SAGAs和(和)了。 上下文:有几个(3+)微服务必须跨越业务事务,以便最终保持数据的一致状态。它们使用每个服务的数据库方法(每个服务将数据存储在Postgres中),并通过Kafka作为事件存储进行协作。 我将应用SAGA(无论是编排还是编排方法,让我们坚持第一种方法)来管理多个服务上的事务。 提前致谢

  • 我的问题很简单。我知道UUID的概念,我想生成一个UUID来引用数据库中“存储”中的每个“项目”。看起来很合理,对吧? 问题是以下行返回错误: 我已经阅读了页面:http://www.postgresql.org/docs/current/static/uuid-ossp.html 我在Ubuntu 10.04 x64上运行Postgres 8.4。

  • 如果另一个客户机在我们调用watch之后更改了powerlevel的值,我们的事务将失败。如果没有客户端更改该值,则该集合将工作。我们可以在循环中执行这段代码,直到它起作用为止。 为什么不能在不能被其他命令打断的事务中执行增量?为什么我们需要迭代而不是等到没有人改变值才开始事务?

  • 问题内容: 我最近在Swift中进行了大量编程。今天,当出现问题时,我在JavaScipt中做了一些工作: 是否有类似于JavaScript中的可选链接的内容?一种防止没有任何变量的方法? 例: 将失败一半的时间,因为有时返回未定义。 我能想到的唯一解决方案是一个函数: 我希望能够执行以下操作: 仅在返回对象后才执行问号后的部分。 但这不是很精巧。有更好的东西吗?运营商的神奇组合? 编辑 我知道我

  • 是否可以在 SQL SERVER 中的事务中使用 SELECT 语句锁定行?我想锁定该行,以便外部的其他事务无法访问该行。 提交或回滚事务后,应释放该行。这就是我的意思。。。 有人有建议吗?我应该执行 UPDATE 语句来锁定该行吗? 请不要将此问题标记为重复问题。因为,我不是在问UPDATE语句,而是在问SELECT 编辑:我试图“设置事务隔离级别串行化”,但这锁定了太多东西。我的SP很大,它有