使用NodeJS和Postgres的事务链中的可选INSERT语句 [英] Optional INSERT statement in transaction chain using NodeJS and Postgres
问题描述
我正在使用 NodeJS / Postgres 构建一个简单的Web应用程序,该应用程序需要在数据库中插入3次。
I'm building a simple webapp using NodeJS/Postgres that needs to make 3 insertions in the database.
要控制链我正在使用 pg-transaction 的语句集。
To control the chain of statements I'm using pg-transaction.
我的问题是我必须始终运行第2个INSERTS,但是我有一个可以运行第三个条件。
My problem is that I have to always run the 2 first INSERTS, but I have a condition to run the 3rd one.
也许我的代码可以更好地构建(欢迎提出建议)。
Maybe my code could be built in a better manner (suggestions are welcome).
这是伪代码:
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!");
});
}
});
});
}
在每个que之后重复相同的 if(err){} 三次,看起来很丑ry。
It looks so ugly to repeat three times the same if (err) {} after each query.
尝试检查一些选项,我发现了 Sequelize ,但找不到解决此问题的方法。
Trying to check some options I found Sequelize, but couldn't see a way to solve this problem with it.
欢迎提出任何建议!
谢谢!
推荐答案
手动事务管理是一个危险的道路,请尝试避免这种情况! ;)
Manual transaction management is a treacherous path, try to steer away from that! ;)
这是在 pg承诺:
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语法:
Or, if you prefer ES7 syntax:
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
/ await
替换了ES6生成器,因为pg-promise已停止从9.0.0版开始支持ES6生成器
Replaced ES6 generators with ES7 async
/await
in the example, because pg-promise stopped supporting ES6 generators from version 9.0.0
这篇关于使用NodeJS和Postgres的事务链中的可选INSERT语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!