【问题标题】:How do sub-queries contained within queries work in pg-promise when using transactions?使用事务时,查询中包含的子查询如何在 pg-promise 中工作?
【发布时间】:2017-05-11 19:09:05
【问题描述】:

我在 node.js 中使用pg-promise,我想确保我正确理解有关事务的文档。

假设我执行了以下交易:

db.tx(function(t) {
  t.any('SELECT * FROM users')
  .then(function(users) {
    var queries = [];
    for (var i =0; i < users.length; i++) {
      queries.push(t.any("INSERT INTO stocks_owned (ticker, shares, user_id) VALUES ('GOOG', 10, $1)", users[i].user_id));
    }
    return t.batch(queries);
  })
})

这最终会执行哪些 postgres 查询?

postgres 交易会是:

BEGIN;
SELECT * FROM users;
SAVEPOINT my_savepoint;
INSERT INTO stocks_owned (ticker, shares, user_id) VALUES ('GOOG', 10, 1);
INSERT INTO stocks_owned (ticker, shares, user_id) VALUES ('GOOG', 10, 2);
...
INSERT INTO stocks_owned (ticker, shares, user_id) VALUES ('GOOG', 10, 999);
COMMIT;

换句话说,包含在其他查询中的子查询是否包含在同一个BEGIN/COMMIT 块中?

【问题讨论】:

    标签: node.js postgresql pg-promise


    【解决方案1】:

    这最终会执行哪些 postgres 查询?

    您列出的那些,除了不会有任何SAVEPOINT,因为保存点仅用于代替嵌套事务。

    包含在其他查询中的子查询是否包含在同一个 BEGIN/COMMIT 块中?

    没有子查询这种东西,从驱动的角度来看,只有查询,所有在事务中执行的都会在BEGIN/COMMIT块内。


    要准确查看pg-promise 正在执行的操作,您应该使用pg-monitor,或者至少 - 处理event query

    var pgOptions = {
        query: function (e) {
            console.log(e.query); // log the query being executed
        }
    };
    
    var pgp = require('pg-promise')(pgOptions);
    

    以下是您的代码中的错误:

    t.any('SELECT * FROM users')
    

    应该是:

    return t.any('SELECT * FROM users')
    

    否则那里没有事务逻辑,因为你没有从回调中返回任何东西。

    执行您在那里尝试的最短和最有效的方法:

    db.tx(t => {
        return t.map('SELECT * FROM users', [], user => {
            return t.none("INSERT INTO stocks_owned(ticker, shares, user_id) VALUES('GOOG', 10, ${user_id})", user);
        }).then(t.batch);
    })
        .then(data => {
            // success, data = [null, null, ...]
        })
        .catch(error => {
            // error
        });
    

    更新

    上面的示例不再是最有效的方法。最有效的方法是执行一次选择,然后执行一次多行插入。见Multi-Row Inserts

    【讨论】:

    • 谢谢!顺便说一句,你的包裹很棒(没有粗俗的双关语)。干杯。
    • “没有子查询之类的东西”。好吧,有子查询这样的东西,但显然不是在 node-pg 级别。子查询是 SQL 中的一种结构,其中一个查询包含另一个查询,例如SELECT ... FROM ... WHERE x = (SELECT ...)SELECT ... FROM (SELECT ..)
    • @CraigRinger 我已将其更正为明确表示from the driver point of view,因为这是我们正在讨论的内容,即对于驱动程序而言,它始终只是一个查询,与其级别无关。
    • @CraigRinger 在你的代码中添加了一个错误的解释;)另见Chaining Queries
    猜你喜欢
    • 2017-10-03
    • 2018-02-19
    • 2017-11-12
    • 2019-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    相关资源
    最近更新 更多