使用事务时,查询中包含的子查询如何在 pg-promise 中工作?
How do sub-queries contained within queries work in pg-promise when using transactions?
我将 pg-promise
用于 node.js,并且我想确保我正确理解了有关交易的文档。
假设我执行了以下交易:
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, )", 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
块中?
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
块内。
要准确查看 pg-promise
正在执行的内容,您应该使用 pg-monitor, or at the very least - handle 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
});
更新
上面的例子不再是最有效的方法。最有效的方法是执行一个 select,然后执行一个多行插入。参见 。
我将 pg-promise
用于 node.js,并且我想确保我正确理解了有关交易的文档。
假设我执行了以下交易:
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, )", 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
块中?
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
块内。
要准确查看 pg-promise
正在执行的内容,您应该使用 pg-monitor, or at the very least - handle 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
});
更新
上面的例子不再是最有效的方法。最有效的方法是执行一个 select,然后执行一个多行插入。参见