node.js - 使用事务时,查询中包含的子查询如何在 pg-promise 中工作?

标签 node.js postgresql pg-promise

我正在为 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 block 中?

最佳答案

What postgres queries will this end up performing?

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

do sub-queries contained within other queries get included in the same BEGIN/COMMIT block?

没有子查询这样的东西,从驱动程序的角度来看,只有查询,所有在事务内执行的都将在 BEGIN/COMMIT block 。


要准确查看 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.js - 使用事务时,查询中包含的子查询如何在 pg-promise 中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38818949/

相关文章:

node.js - 如何在 puppeteer 中处理多个窗口?

javascript - 如何使用node-postgres设置模式

带有 CORS 转储数据的 Django 1.9 : "corsheaders_corsmodel" does not exist

javascript - 如何使用 pg-promise 一次从多个查询中获取结果?

node.js - 在 pg-promise 中跨多个 Controller 的多个查询之间共享事务或任务对象

javascript - Node.js 以错误的顺序循环打印

angularjs - nodemon 应用程序崩溃 - 在启动之前等待文件更改

node.js - 使用 Socket.IO 的 letsencrypt-express

node.js - Sequelize 和 express-session 模型

node.js - pg-promise 将整数作为字符串返回